问题
I want to create a checkboxlist in asp.net mvc view and want to display week days (monday tuesday, ....). I want to save the value(s) selected by user in database. How can I do this in MVC2
Someone suggested me to use "Enumeration Types as Bit Flags" mentioned here:
http://msdn.microsoft.com/en-us/library/cc138362.aspx
how can I use it ?
Please suggest solution.
回答1:
Yes i would also suggest an enum in this scenario.
Here is how you can do it in ASP.NET MVC:
Your enum should look like this (see the link you provided):
[Flags]
public enum Days
{
Sunday = 0x1,
Monday = 0x2,
Tuesday = 0x4,
Wednesday = 0x8,
Thursday = 0x10,
Friday = 0x20,
Saturday = 0x40
}
For reusability purposes I have created an generic html helper that looks like this:
public static IHtmlString CheckboxListForEnum<T>(this HtmlHelper html, string name, T modelItems) where T : struct
{
StringBuilder sb = new StringBuilder();
foreach (T item in Enum.GetValues(typeof(T)).Cast<T>())
{
TagBuilder builder = new TagBuilder("input");
long targetValue = Convert.ToInt64(item);
long flagValue = Convert.ToInt64(modelItems);
if ((targetValue & flagValue) == targetValue)
builder.MergeAttribute("checked", "checked");
builder.MergeAttribute("type", "checkbox");
builder.MergeAttribute("value", item.ToString());
builder.MergeAttribute("name", name);
builder.InnerHtml = item.ToString();
sb.Append(builder.ToString(TagRenderMode.Normal));
}
return new HtmlString(sb.ToString());
}
You can use the same html helper for all enumeration types.
Usage:
Now for demonstration purposes let say that you have a model like this:
Model:
public class TVShow
{
public string Title { get; set; }
public string Description { get; set; }
public Days AvailableOn { get; set; }
}
Controller Action:
public ActionResult Show()
{
var show = new TVShow
{
Title = "Late Late Show",
AvailableOn = Days.Monday | Days.Friday
};
return View(show);
}
View (strongly typed):
<%: Model.Title %>
<%: Model.Description %>
<%: Html.CheckboxListForEnum<Days>("days", Model.AvailableOn)%>
回答2:
There is even simpler way - use custom @Html.CheckBoxList() extension from here: http://www.codeproject.com/KB/user-controls/MvcCheckBoxList_Extension.aspx
Usage example (MVC2 view with Razor view engine):
<%= Html.CheckBoxList("NAME", // NAME of checkbox list
x => x.DataList, // data source (list of 'DataList' in this case)
x => x.Id, // field from data source to be used for checkbox VALUE
x => x.Name, // field from data source to be used for checkbox TEXT
x => x.DataListChecked // selected data (list of selected 'DataList' in thiscase),
// must be of same data type as source data or set to 'NULL'
) %>
回答3:
its that easy:
1. create the checkbox class with string id and bool value.
2. put list of checkbox in the controller method with some name.
3. create 2 fields dynamically in your view but make sure you conform to the razor engine naming system.
to create a dynamic checkbox list you need to understand the way the razor engine works,
say you have this code
in the head of the view you include a model like so:
@model MyProject.Site.Models.MyWebModel
that model has a setting class that has a bool inside like so:
public class MyWebModel
{
public HighchartsSettingModel Settings { get; set; }
}
public class HighchartsSettingModel
{
public bool JoinSameType{ get; set; }
}
and in the view you have:
@Html.CheckBoxFor(x => x.Settings.JoinSameType)
in short this creates the following html code:
<input data-val="true" data-val-required="The JoinSameType field is required." id="Settings_JoinSameType" name="Settings.JoinSameType" type="checkbox" value="true" />
<input name="Settings.JoinSameType" type="hidden" value="false" />
so far so good for the CheckBoxFor, that is a part of the framwork, how do we work with arrays?
so now all we need to do is to understand how to work with list in a controller method, say you have this class:
public class Checkbox{
public string Id { get; set; }
public bool Value { get; set; }
}
and in the controller you have this:
public ActionResult SensorSearch(List<Checkbox> selectedSensors, string search, string subSearch, string page, string back)
and the view will look like so:
@{
int counter = 0;
string id_name, id_id, value_id, value_name;
}
@foreach (var item in Model.SensorList)
{
id_id = "selectedSensors_" + counter + "__Value";
id_name = "selectedSensors[" + counter + "].Value";
value_id = "selectedSensors_" + counter + "__Id";
value_name = "selectedSensors[" + counter + "].Id";
counter++;
<li><a href="#" style="padding-top: 0px;padding-bottom: 0px;padding-right: 42px;padding-left: 0px;">
<label style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;" data-corners="false">
<fieldset data-role="controlgroup" >
<input id="@id_id" name="@id_name" type="checkbox" value="true" />
<input id="@value_id" name="@value_name" type="hidden" value="@item.Key" />
<label for="@id_id" style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;">
<label style="padding:10px 0px 0px 10px;">
<h3>@item.Key</h3>
<p>User Name: @item.Value</p>
</label>
</label>
</fieldset>
</label>
</a><a href="#" rel="external"></a>
</li>
}
</ul>
lets not forget the form in the view:
@using (Html.BeginForm("SensorSearch", "Home", Model.PageNav.StayRouteValues, FormMethod.Post, new Dictionary<string, object>() { { "data-ajax", "false" }, { "id", "sensor_search_form" } }))
now the rendered page will look like so in the checkbox aspect:
<li><a href="#" style="padding-top: 0px;padding-bottom: 0px;padding-right: 42px;padding-left: 0px;">
<label style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;" data-corners="false">
<fieldset data-role="controlgroup" >
<input id="selectedSensors_16__Value" name="selectedSensors[16].Value" type="checkbox" value="true" />
<input id="selectedSensors_16__Id" name="selectedSensors[16].Id" type="hidden" value="10141" />
<label for="selectedSensors_16__Value" style="border-top-width: 0px;margin-top: 0px;border-bottom-width: 0px;margin-bottom: 0px;border-left-width: 0px;border-right-width: 0px;">
<label style="padding:10px 0px 0px 10px;">
<h3>10141</h3>
<p>User Name: 10141_TEN-2MP</p>
</label>
</label>
</fieldset>
</label>
</a><a href="#" rel="external"></a>
</li>
what you need to notice is the names given to the input-checkbox and the input-hidden we used it similar to the way razor engine creates name and so after submit the engine will render this as an array and so you can create any dynamic checkbox list where ever you want same as you would in any other language (say php and so...) .
its that easy:
its that easy:
1. create the checkbox class with string id and bool value.
2. put list of checkbox in the controller method with some name.
3. create 2 fields dynamically in your view but make sure you conform to the razor engine naming system.
i hoped it helped.
来源:https://stackoverflow.com/questions/6217747/checkboxlist-in-asp-net-mvc