Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>Part 1: Explaining Lambda magic</h1> <p>You're not alone. Lambdas + MVC make coding wicked easy, but they also make it seem rather magical (due to the abstraction).</p> <blockquote> <p>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?</p> </blockquote> <p>Yes.</p> <p>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.</p> <p>First, let's take a look at <code>@Html</code>. We know <code>@</code> begins our Razor syntax and then <code>Html</code> is magic. Actually, <code>Html</code> is an <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper%28v=vs.108%29.aspx">HtmlHelper</a> object that is automatically initialised and given to you. More specifically it's an <code>HtmlHelper&lt;TModel&gt;</code>. 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.</p> <p>When you type</p> <pre><code>@model IEnumerable&lt;BusinessLayer.Employee&gt; </code></pre> <p>The editor reads that and makes an assumption now that the HTML Helper will be <code>HtmlHelper&lt;IEnumerable&lt;BusinessLayer.Employee&gt;&gt;</code>. When it comes time to compile the page, the HTML helper will in fact be that type (of course).</p> <p>So what about <code>DropDownListFor</code> or any other extension method?</p> <p>Looking at <a href="http://msdn.microsoft.com/en-us/library/ee703573%28v=vs.108%29.aspx">DropDownListFor</a> we can see that it's actually <code>DropDownListFor&lt;TModel, TProperty&gt;</code>. We now understand that TModel is our view's model type. <code>DropDownListFor</code> knows about this because the method is <strong>extending</strong> <code>HtmlHelper&lt;TModel&gt;</code>. Therefore DropDownListFor knows that the incoming type is whatever type is defined at the top of the view. What about <code>TProperty</code>?</p> <p><code>TProperty</code> 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: <code>(x =&gt; x.Property)</code> you select the property which then selects the type for you; in this case a <strong>string</strong> (Gender).</p> <h1>Part 2: Your problem</h1> <p>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?</p> <p>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.</p> <p>I don't really like the idea of a single view getting a collection of things on a page. Consider this piece of logic:</p> <h2>Your way:</h2> <ul> <li>Get collection of Employees</li> <li>Give Employees to a view</li> <li>Have view create a single SelectListItem</li> <li>Loop through and display the SelectList for each Employee</li> </ul> <h2>My way</h2> <ul> <li>Get collection of Employees</li> <li>Give employees to a view</li> <li>Have the view loop through and pass each Employee to another view (partial)</li> <li>Each partial deals with a single Employee</li> </ul> <p>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.</p> <h2>Example solution walk-through</h2> <p>Try this:</p> <p>Create a new PartialView called _<em>EmployeeGender.cshtml</em> in the same folder as the view you're using.</p> <p>Use this code</p> <p><strong>_EmployeeGender.cshtml</strong></p> <pre><code>@model BusinessLayer.Employee &lt;tr&gt; &lt;td&gt; @{ var listItems = new List&lt;SelectListItem&gt;() { new SelectListItem {Text = "Male", Value = "M"}, new SelectListItem {Text = "Female", Value = "F"} }; @Html.DropDownListFor(m =&gt; m.Gender, listItems, string.Empty) } &lt;/td&gt; &lt;/tr&gt; </code></pre> <p><strong>Your original view</strong></p> <pre><code>@model IEnumerable&lt;BusinessLayer.Employee&gt; @{ ViewBag.Title = "Employees"; } &lt;h2&gt;Employees&lt;/h2&gt; &lt;table&gt; @foreach (var employee in Model) { Html.RenderPartial("_EmployeeGender", employee); } &lt;/table&gt; </code></pre> <h2>Results</h2> <p>Let's have a look at our <strong>generated HTML</strong> now:</p> <pre><code>&lt;table&gt; &lt;tr&gt; &lt;td&gt; &lt;select id="Gender" name="Gender"&gt;&lt;option value=""&gt;&lt;/option&gt; &lt;option selected="selected" value="M"&gt;Male&lt;/option&gt; &lt;option value="F"&gt;Female&lt;/option&gt; &lt;/select&gt; &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt; &lt;select id="Gender" name="Gender"&gt;&lt;option value=""&gt;&lt;/option&gt; &lt;option value="M"&gt;Male&lt;/option&gt; &lt;option selected="selected" value="F"&gt;Female&lt;/option&gt; &lt;/select&gt; &lt;/td&gt; &lt;/tr&gt;&lt;/table&gt; </code></pre> <p>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).</p> <p><strong>Do Note</strong> that the <code>id</code> and <code>name</code> 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.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload