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))

这是这里发生的事情:

  1. y - 1 将复选框值 y 转换为零索引位位置。
  2. 1 << (y-1) 产生值 2y-1,即仅设置位置 y-1 中的位的值。
  3. 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/