1

我将 ASP.NET MVC3 与 Razor 一起使用。

我的模型中有一个布尔值,我想在视图中将其呈现为复选框。但是,我希望复选框指示布尔状态的反转。换句话说,选中复选框应该在提交表单时将绑定模型对象设置为 false,而不是 true。反之亦然。

我可以这样做来在渲染的复选框输入元素上设置 value 属性:

@Html.CheckBoxFor(model => model.MyBoolean, new { value = "false" })

但是自动创建的隐藏输入元素的值仍然为 false。因此,它们的值都为 false,这意味着绑定的模型对象始终设置为 false。

那么如何强制 HTML 助手将隐藏元素设置为 true 并将复选框元素设置为 false 呢?

我知道(a)我可以更改模型和数据库,(b)我可以在提交之前使用 javascript 更改值,以及(c)我可以在提交后交换控制器中收到的任何值。我可能会做其中之一,但我不是在寻求可能的解决方案;我在问是否可以让 HTML 助手按照我的意愿去做。我进行了广泛的搜索,但在官方或非官方来源的任何地方都没有看到这个问题。似乎他们应该有一个“交换”选项或其他东西。

4

3 回答 3

3
    class ViewModel {
        public bool MyBoolean {get;set;}
        public bool DisplayValue {
            get {
                return ! MyBoolean ;
            }

            set {
                MyBoolean = !value;
            }
        }
    }

并绑定到,因为它的设置器无论如何DisplayValue都会更新您的属性。MyBoolean

编辑:

再次阅读您的问题:.

您可以使用 HtmlHelper 来做到这一点 - 但不是使用 CheckBox,您可以使用下拉菜单。下拉列表将定义“相反”的值和文本。

    myModelInstance.PossibleValues = new[] { new SelectListItem { Value = "false", Text = "Not false" }, new SelectListItem { Value = "true", Text = "Not true" } };

请注意描述与您希望模型的含义相反。所以例如。如果为 true,您可能会将文本设置为“隐藏”,而 false 您可能会将文本设置为“可见”,为“已禁用”为“真”,“已启用”为“假”等。

然后在您的视图中:

    @Html.DropDownList(Model.MyBoolean.ToString(), Model.PossibleValues)

模型将使用正确的值更新,而无需在查看或更新之前进行布尔切换。

于 2013-01-17T19:39:13.597 回答
0

对于未来的读者,我个人认为,HtmlHelpers 旨在呈现 Html(顾名思义)。我更喜欢创建不同的方式来呈现项目是创建 EditFor 和 DisplayFor 模板。为了确保这是高度可重用的,我还创建了专门为这些模板设计的模型。使用您的设计,我的模型和模板可能如下所示:

/Models/Controller/ControllerActionViewModel.cs

public class ControllerActionViewModel
{
  public ControllerActionViewModel()
  {
    this.CheckboxBoolTemplate = new CheckboxBoolTemplate(false, true);
  }

  [Display(Name = "My Boolean")]
  public SelectBoolTemplate MyBoolean { get; set; }
}

/TemplateModels/ControllerActionViewModel.cs

public sealed class SelectBoolTemplate
{
  private bool _valuesSwapped = false;
  private bool? _value;
  private bool _defaultValue = false;

  public SelectBoolTemplate()
  {
  }

  public SelectBoolTemplate(bool valuesSwapped)
  {
    this._valuesSwapped = valuesSwapped)
  }

  public SelectBoolTemplate(bool defaultValue, bool valuesSwapped)
  {
    this._defaultValue = defaultValue;
    this._valuesSwapped = valuesSwapped)
  }

  public bool Value
  {
    get
    {
      if (this._value.HasValue)
      {
        return this._value.Value
      }
      return this._defaultValue;
    }
    set
    {
      this._value = value;
    }
  }
}

/Views/Shared/EditorTemplates/SelectBoolTemplate.cshtml

@model SelectBoolTemplate

@{
string propertyName = ViewContext.ViewData.ModelMetadata.PropertyName;
string fullPropertyName = ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
string labelText = ViewContext.ViewData.ModelMetadata.DisplayName 
                   ?? ViewContext.ViewData.ModelMetadata.PropertyName;
}

@Html.LabelForModel()
@Html.Checkbox(fullPropertyName, Model.Value)
于 2013-01-18T19:01:05.523 回答
0

我知道这对于原始查询来说为时已晚,但是对于将来阅读的任何人来说,有另一种方法可以处理复选框,其中选中/未选中的反向 false/true 不需要更改模型 - 创建一个 false 复选框和一个隐藏字段真的

<input id="@Html.IdFor(model => model.BoolProperty)" name="@Html.NameFor(model => model.BoolProperty)" type="checkbox" value="false" @(Model.BoolProperty? "" : "checked=\"checked\"" ) />
<input name="@Html.NameFor(model => model.BoolProperty)" type="hidden" value="true" />
于 2017-08-14T09:28:41.957 回答