我正在处理一个与我无法更改的现有数据库相关联的网页:(。页面有一个复选框列表。该列表有四个复选框。复选框的值为1,2,3;在我之前有人决定将这些选定的组合存储为数据库中的可空tinyint
。在我的C#代码中,tinyint
变为short?
。
要将所选值存储在数据库中,控制器中会出现如下代码:
var selectedValues = new List<short>();
foreach (string v in model.ValueList)
{
short t = -1;
if (Int16.TryParse(v, out t))
selectedValues.Add(t);
}
model.SelectedValues = (short)(selectedValues .Aggregate(0, (x, y) => x | 1 << (y - 1)));
这是值持久化的方式。我看到像5,11等的值。但是,列表中的复选框不会重新填充。我在MVC视图中看到以下代码。
@foreach (var v in Model.ValueList)
{
var isChecked = false;
if (Model.SelectedValues.HasValue)
{
// TODO. use bit operation to determine if the checkbox was
// selected
}
<label class="checkbox">
<input type="checkbox" name="ValueList" />
@v.Text
</label>
}
todo
阻止了我的循环。我不确定如何正确使用按位操作来确定是否应该选中复选框。我怎么能这样做呢? (我甚至可以这样做吗?)
答案 0 :(得分:0)
Aggregate(0, (x, y) => x | 1 << (y - 1))
以下是这里发生的事情:
y - 1
将复选框值y
转换为零索引位位置。1 << (y-1)
产生值2 y-1 ,即只设置位置y-1
中的位的值。x | 1 << (y-1)
通过按位OR
将步骤2中生成的值与迄今为止的总结果相结合,在这种情况下等效于加法,因为没有两个值组合在一起设置了位同样的立场。当且仅当y
中的位y-1
被设置时,才会检查其值为Model.SelectedValues
的复选框。换句话说,当且仅当:
(Model.SelectedValues & (1 << (y - 1))) > 0
不过,我不会在你的视图中放置这样的代码。如果它以这种方式存储在数据库中而你无法改变它,那么就这样吧,但你应该能够将数据库值转换为一种格式,你可以在加载它时更直观地使用它,这样你就可以每次需要访问数据时都要避免这种麻烦。
答案 1 :(得分:0)
首先,我将创建一个视图模型来表示所选的值,即
public class Selection
{
public short ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
}
在当前模型中添加属性以表示复选框列表,即
public class AModel
{
public AModel()
{
CheckBoxList = new List<Selection>();
}
public List<Selection> CheckBoxList { get; set; }
// existing properties
}
从控制器开始,您需要有一个可用选项列表。然后循环这些设置Checked
属性如下(请注意,如果没有看到您的代码我假设AvailableSelections
属性是短裤列表):
// Build up a list of the entire checkboxes
var checkBoxList = new List<Selection>();
foreach(var shortValue in Model.`AvailableSelections`)
{
checkBoxList.Add(new Selection { ID = shortValue, Name = shortValue.ToString() });
}
model.CheckBoxList = checkBoxList;
// Select the values
foreach (short v in model.ValueList)
{
var checkBox = checkBoxList.FirstOrDefault(c => c.Id == v);
checkBox.Checked = true;
}
然后在您的视图中,您可以使用Html.CheckBoxFor
@for(var i = 0; i < Model.CheckBoxList.Count; i++)
{
<label class="checkbox">
@Html.HiddenFor(m => Model.CheckBoxList[i].ID)
@Html.HiddenFor(m => Model.CheckBoxList[i].Name)
@Html.CheckBoxFor(m => Model.CheckBoxList[i].Checked)
@Model[i].Name
</label>
}
注意for循环而不是foreach来启用模型绑定,隐藏字段允许将值发布回控制器
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/