C# @Html.DropDownListFor 基本用法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19720327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@Html.DropDownListFor Basic Usage
提问by Chad
I'm just starting to learn MVC4 and I must admit I'm a little challenged by all the reliance on lambda expressions, generics and anonymous types, especially when there are many overloaded functions. It's a bit confusing to try and understand how the HTML Helpers work. Take the "DropDownListFor" Helper, for example. I tried to extract the essentials from my code. That's why you see only a only a single column, "Gender", in the table. Hopefully it is still syntactically correct:
我刚刚开始学习 MVC4,我必须承认我对 lambda 表达式、泛型和匿名类型的所有依赖有点挑战,尤其是当有许多重载函数时。尝试理解 HTML 帮助程序的工作方式有点令人困惑。以“DropDownListFor”助手为例。我试图从我的代码中提取要点。这就是为什么您在表中只看到一列“性别”。希望它在语法上仍然是正确的:
@model IEnumerable<BusinessLayer.Employee>
<table>
@foreach (var employee in Model)
{
<tr>
<td>
@{
var listItems = new List<SelectListItem>()
{
new SelectListItem {Text = "Male", Value = "M"},
new SelectListItem {Text = "Female", Value = "F"}
};
@Html.DropDownListFor(m => employee.Gender, listItems, listItems.Find(i => i.Value == employee.Gender).Text)
}
</td>
</tr>
}
</table>
There are two Employees in the Model object, an IEnumerable of Employee and the following HTML is generated
Model对象中有两个Employees,一个Employee的IEnumerable,生成如下HTML
<table>
<tr>
<td>
<select id="employee_Gender" name="employee.Gender"><option value="">Male</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</tr>
</td>
<select id="employee_Gender" name="employee.Gender"><option value="">Female</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</td>
</table>
Looking at the first param of the DropDownListFor Method,
查看 DropDownListFor 方法的第一个参数,
@Html.DropDownListFor(m => employee.Gender, ...
...Do I understand correctly that the "m" represents the instance of the model class that was passed into the View? In the online examples that I have seen, I have seen examples where the "m" appears to refer to the model class but where the model is a single instance class, for example, a single Employee object, rather than a collection of Employees as is the case here where I want to display a table list of Employees. I'm assuming that the intent of the first param of the DropDownListFor Method is "point/bind' to a propertyin the model, so that's why I made m => employee.Gender. Is this what I should be doing when the model is a collection of Employees rather than a single Employee? If so, I am confused as to how I can generate unique IDs for the two drop down lists which were both assigned "employee_Gender" for both the NAME and ID attributes.
...我是否正确理解“m”代表传递到视图中的模型类的实例?在我看到的在线示例中,我看到了一些示例,其中“m”似乎是指模型类,但模型是单个实例类,例如,单个 Employee 对象,而不是Employees 的集合作为这里就是我想显示员工表列表的情况。我假设 DropDownListFor 方法的第一个参数的意图是“指向/绑定”到一个属性在模型中,这就是我制作 m => employee.Gender 的原因。当模型是员工的集合而不是单个员工时,这是我应该做的吗?如果是这样,我很困惑如何为两个下拉列表生成唯一 ID,这两个下拉列表都为 NAME 和 ID 属性分配了“employee_Gender”。
For the 3rd parameter of the Helper DropDownListFor,
对于 Helper DropDownListFor 的第三个参数,
listItems.Find(i => i.Value == employee.Gender).Text
Is this reasonable? The value for employee.Gender is either "M" or "F" but the display Text is "Male" and "Female." I am confused whether this param is used to specify a default "NO SELECT" first value or whether this param is used to select from the drop down the value of the current Employee---or perhaps it can do both? For example, does it select the Textspecified if found and otherwise add the text specified as the FIRST?parameter if the value is not found? That appears to be how it works from what I see. Can this 3rd param be simplified or is my example reasonable?
这合理吗?employee.Gender 的值是“M”或“F”,但显示文本是“Male”和“Female”。我很困惑这个参数是否用于指定默认的“NO SELECT”第一个值,或者这个参数是否用于从下拉列表中选择当前员工的值——或者它可能两者都做?例如,它是否选择指定的文本(如果找到)并添加指定为FIRST的文本?如果未找到该值的参数?从我所见,这似乎是它的工作原理。这第三个参数可以简化还是我的例子合理?
Thanks for your patience in reading my many flurry of questions in trying to better understand this.
感谢您耐心阅读我的一系列问题,以便更好地理解这一点。
采纳答案by Rowan Freeman
Part 1: Explaining Lambda magic
第 1 部分:解释 Lambda 魔法
You're not alone. Lambdas + MVC make coding wicked easy, but they also make it seem rather magical (due to the abstraction).
你不是一个人。Lambdas + MVC 使编码变得很容易,但它们也使它看起来很神奇(由于抽象)。
Looking at the first param of the DropDownListFor Method [...] Do I understand correctly that the "m" represents the instance of the model class that was passed into the View?
查看 DropDownListFor 方法的第一个参数 [...] 我是否正确理解“m”表示传递到视图中的模型类的实例?
Yes.
是的。
HTML Helpers + Lambdas in Razor are simple and magical because they are taking a shortcut and not actually revealing to you what's going on.
Razor 中的 HTML Helpers + Lambdas 简单而神奇,因为它们走的是捷径,实际上并没有向您透露正在发生的事情。
First, let's take a look at @Html
. We know @
begins our Razor syntax and then Html
is magic. Actually, Html
is an HtmlHelperobject that is automatically initialised and given to you. More specifically it's an HtmlHelper<TModel>
. The Razor HTML editor is smart and knows ahead of time what type TModel will be based on what you've said this view's model type is. That's why you have so much intellisense.
首先,让我们来看看@Html
。我们知道@
开始我们的 Razor 语法然后Html
是魔法。实际上,Html
是一个自动初始化并提供给您的HtmlHelper对象。更具体地说,它是一个HtmlHelper<TModel>
. Razor HTML 编辑器很聪明,并且根据您所说的此视图的模型类型提前知道 TModel 将是什么类型。这就是为什么你有这么多的智能。
When you type
当你输入
@model IEnumerable<BusinessLayer.Employee>
The editor reads that and makes an assumption now that the HTML Helper will be HtmlHelper<IEnumerable<BusinessLayer.Employee>>
. When it comes time to compile the page, the HTML helper will in fact be that type (of course).
编辑器读取该内容并假设 HTML Helper 将是HtmlHelper<IEnumerable<BusinessLayer.Employee>>
. 当需要编译页面时,HTML 助手实际上就是那种类型(当然)。
So what about DropDownListFor
or any other extension method?
那么DropDownListFor
或者任何其他扩展方法呢?
Looking at DropDownListForwe can see that it's actually DropDownListFor<TModel, TProperty>
. We now understand that TModel is our view's model type. DropDownListFor
knows about this because the method is extendingHtmlHelper<TModel>
. Therefore DropDownListFor knows that the incoming type is whatever type is defined at the top of the view. What about TProperty
?
查看DropDownListFor我们可以看到它实际上是DropDownListFor<TModel, TProperty>
. 我们现在明白 TModel 是我们视图的模型类型。DropDownListFor
知道这一点,因为该方法正在扩展HtmlHelper<TModel>
。因此 DropDownListFor 知道传入类型是视图顶部定义的任何类型。怎么样TProperty
?
TProperty
is the return type. That's the type that you specify when you select your property. The view gives HtmlHelper the model type, who then gives DropDownListFor the model type and now that you're in a lambda expression: (x => x.Property)
you select the property which then selects the type for you; in this case a string(Gender).
TProperty
是返回类型。这是您在选择属性时指定的类型。该视图为 HtmlHelper 提供了模型类型,然后他提供了 DropDownListFor 模型类型,现在您处于 lambda 表达式中:(x => x.Property)
您选择属性,然后为您选择类型;在这种情况下是一个字符串(性别)。
Part 2: Your problem
第 2 部分:您的问题
It's hard to answer your question without knowing exactly what you're trying to achieve. Do you have a collection of Employees and you want to display multiple gender dropdown boxes for each and then save them?
如果不确切知道您要实现的目标,就很难回答您的问题。您是否有一组员工,并且想要为每个员工显示多个性别下拉框,然后保存它们?
When dealing with collections it's a little more tricky, since MVC doesn't handle them well out of the box; it's usually best to write your own solutions according to what you need done.
在处理集合时,它有点棘手,因为 MVC 不能很好地处理它们。通常最好根据您的需要编写自己的解决方案。
I don't really like the idea of a single view getting a collection of things on a page. Consider this piece of logic:
我真的不喜欢单个视图在页面上获取事物集合的想法。考虑这个逻辑:
Your way:
你的方式:
- Get collection of Employees
- Give Employees to a view
- Have view create a single SelectListItem
- Loop through and display the SelectList for each Employee
- 获取员工集合
- 给员工一个视图
- 让视图创建单个 SelectListItem
- 循环并显示每个员工的 SelectList
My way
我的方式
- Get collection of Employees
- Give employees to a view
- Have the view loop through and pass each Employee to another view (partial)
- Each partial deals with a single Employee
- 获取员工集合
- 给员工一个视图
- 让视图循环并将每个员工传递到另一个视图(部分)
- 每个部分处理一个员工
With MVC do try to break things down into small, logical parts. Views should be stupid; meaning they shouldn't really do any logic or thinking. Things become easier this way and it makes sure that your views don't grow into monsters.
使用 MVC 确实尝试将事情分解成小的、合乎逻辑的部分。观点应该是愚蠢的;这意味着他们不应该真正做任何逻辑或思考。这样事情会变得更容易,它可以确保您的视图不会变成怪物。
Example solution walk-through
示例解决方案演练
Try this:
尝试这个:
Create a new PartialView called _EmployeeGender.cshtmlin the same folder as the view you're using.
在与您使用的视图相同的文件夹中创建一个名为 _ EmployeeGender.cshtml的新 PartialView 。
Use this code
使用此代码
_EmployeeGender.cshtml
_EmployeeGender.cshtml
@model BusinessLayer.Employee
<tr>
<td>
@{
var listItems = new List<SelectListItem>()
{
new SelectListItem {Text = "Male", Value = "M"},
new SelectListItem {Text = "Female", Value = "F"}
};
@Html.DropDownListFor(m => m.Gender, listItems, string.Empty)
}
</td>
</tr>
Your original view
你原来的看法
@model IEnumerable<BusinessLayer.Employee>
@{
ViewBag.Title = "Employees";
}
<h2>Employees</h2>
<table>
@foreach (var employee in Model)
{
Html.RenderPartial("_EmployeeGender", employee);
}
</table>
Results
结果
Let's have a look at our generated HTMLnow:
现在让我们看看我们生成的 HTML:
<table>
<tr>
<td>
<select id="Gender" name="Gender"><option value=""></option>
<option selected="selected" value="M">Male</option>
<option value="F">Female</option>
</select>
</td>
</tr><tr>
<td>
<select id="Gender" name="Gender"><option value=""></option>
<option value="M">Male</option>
<option selected="selected" value="F">Female</option>
</select>
</td>
</tr></table>
We can see that there is now a blank selection and that our dropdown boxes are automatically selected with the Employee's values (I create one male and one female employee).
我们可以看到现在有一个空白选择,我们的下拉框自动选择了员工的值(我创建了一名男性和一名女性员工)。
Do Notethat the id
and name
HTML attributes are the same. If you want to submit a form with these values then it will require more work. But this is a reasonable starting point for you.
请注意,id
和name
HTML 属性是相同的。如果您想提交具有这些值的表单,则需要更多的工作。但这对您来说是一个合理的起点。