C# - 确定值是否为字节值
C# - Determining if Value is In byte value
我正在处理与我无法更改的现有数据库关联的网页:(。该页面有一个复选框列表。该列表有四个复选框。复选框的值为 1、2、3 , 和 4. 在我之前有人决定将这些选定的组合存储为数据库中可为空的 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
块让我陷入困境。我不确定如何正确使用按位运算来确定是否应选中复选框。我到底该怎么做? (我能做到吗?)
Aggregate(0, (x, y) => x | 1 << (y - 1))
这是这里发生的事情:
y - 1
将复选框值 y
转换为零索引位位置。
1 << (y-1)
产生值 2y-1,即仅设置位置 y-1
中的位的值。
x | 1 << (y-1)
通过按位 OR
将步骤 2 中产生的值与迄今为止的总体结果组合起来,在这种情况下,这相当于加法,因为没有两个组合的值有位设置在相同的位置。
因此,当且仅当 Model.SelectedValues
中的位 y-1
已设置时,才会选中值为 y
的复选框。换句话说,当且仅当:
(Model.SelectedValues & (1 << (y - 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/
我正在处理与我无法更改的现有数据库关联的网页:(。该页面有一个复选框列表。该列表有四个复选框。复选框的值为 1、2、3 , 和 4. 在我之前有人决定将这些选定的组合存储为数据库中可为空的 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
块让我陷入困境。我不确定如何正确使用按位运算来确定是否应选中复选框。我到底该怎么做? (我能做到吗?)
Aggregate(0, (x, y) => x | 1 << (y - 1))
这是这里发生的事情:
y - 1
将复选框值y
转换为零索引位位置。1 << (y-1)
产生值 2y-1,即仅设置位置y-1
中的位的值。x | 1 << (y-1)
通过按位OR
将步骤 2 中产生的值与迄今为止的总体结果组合起来,在这种情况下,这相当于加法,因为没有两个组合的值有位设置在相同的位置。
因此,当且仅当 Model.SelectedValues
中的位 y-1
已设置时,才会选中值为 y
的复选框。换句话说,当且仅当:
(Model.SelectedValues & (1 << (y - 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/