ASP.NET MVC3 @Html.EditorFor Checkbox disable enab

2019-06-22 00:15发布

问题:

I am working in ASP.NET MVC3 using Razor. I have a situation where I want to enable disable a checkbox based on a boolean property. My model class has 2 properties like:

public bool IsInstructor { get; set; }
public bool MoreInstructorsAllowed { get; set; }

Now in my cshtml file, I am showing the checkbox as:

@Html.EditorFor(model => model.IsInstructor)

I want this checkbox to enable disable on basis of MoreInstructorsAllowed property. Thanks in advance for the solution. :)

回答1:

The EditorFor extension method wires up your Model to the PartialView that is located in the EditorTemplates file that corresponds to the type of the Model (so in this case, it would need to be Boolean.cshtml).

You can accomplish your objective by adding conditional logic to the Editor Template. You will also need to give the partial a way to know what value the MoreInstructorsAllowed property has, and you can use the EditorFor overload with the additionalViewData parameter to pass this information.

Honestly, changing the default functionality of processing booleans seems like its a little much for what you are trying to do. If these two fields are fundamentally linked, it would make more sense to make a composite of the two fields and wire up a partial view to the composite rather than the to the booleans themselves. What I mean is:

public class InstructorProperty { 
    public bool IsInstructor { get; set; }
    public bool MoreInstructorsAllowed { get; set; }
}

and in /Shared/EditorTemplates/InstructorProperty.cshtml

@model InstructorProperty

//  ...  Your view logic w/ the @if(MoreInstructorsClause) here.

The only problem is that now you are back at the problem of having to use the CheckboxFor method in order to apply the "disabled" attribute, because the EditorFor methods don't accept ad hoc html attributes. There is a known work around that involves overriding your ModelMetadataProvider and decorating the property with an attribute that you provide handling for in the ModelMetadataProvider. A working example of this technique is available at: http://aspadvice.com/blogs/kiran/archive/2009/11/29/Adding-html-attributes-support-for-Templates-2D00-ASP.Net-MVC-2.0-Beta_2D00_1.aspx . However, that's still going to involve either: (1) overriding the Boolean view and either hard-coding the html or using CheckboxFor in there, (2) using a CheckboxFor method in the InstructorProperty view, or (3) hard-coding the html into the InstructorProperty view. I don't think it makes sense to over complicate design for such a trivial thing, so my solution would be to use this InstructorProperty view and just add:

@Html.CheckboxFor(_=>_.IsInstructor, 
    htmlAttributes: (Model.MoreInstructorsAllowed ? null : new { disabled = "disabled"} ).ToString().ToLowerInvariant() });        

But I get that everyone has different styles... One other side note. If your aversion to using the Checkbox method is related to the generated naming scheme, the way that the Mvc Framework accesses this feature involves html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)