asp.net-mvc ASP.NET MVC 2 - HTML.EditorFor() 和自定义 EditorTemplates

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1235646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:46:02  来源:igfitidea点击:

ASP.NET MVC 2 - HTML.EditorFor() and Custom EditorTemplates

asp.net-mvctemplatespreview

提问by Nathan Taylor

With MVC 2's addition of the HtmlHelper EditorFor() it is not possible to create strongly typed Display and Editor templates for a given Model object and after fiddling with it I am a bit stumped as to how to pass additional Model data to the editor without losing the strong-typing of the editor control.

随着 MVC 2 添加了 HtmlHelper EditorFor(),无法为给定的 Model 对象创建强类型的 Display 和 Editor 模板,在摆弄它之后,我对如何将额外的 Model 数据传递给编辑器而不会丢失感到有点困惑编辑器控件的强类型。

Classic Example: Product has Category. ProductEditor has a DropDownList for Category containing the names of all Categories. The ProductEditor is strongly typed to Product and we need to pass in the SelectList of Categories as well as the Product.

经典示例:产品具有类别。ProductEditor 有一个包含所有类别名称的类别的下拉列表。ProductEditor 被强类型化为Product,我们需要传入Categories 的SelectList 以及Product。

With a standard view we would wrap the Model data in a new type and pass that along. With the EditorTemplate we lose some of the standard functionality if we pass in a mixed Model containing more than one object (first thing I noticed was all of the LabelFor/TextBoxFor methods were producing entity names like "Model.Object" rather than just "Object").

使用标准视图,我们会将模型数据包装在新类型中并将其传递。使用 EditorTemplate,如果我们传入一个包含多个对象的混合模型,我们会失去一些标准功能(我注意到的第一件事是所有 LabelFor/TextBoxFor 方法都在生成诸如“Model.Object”之类的实体名称,而不仅仅是“Object” ”)。

Am I doing it wrong or should Html.EditorFor() have an additional ViewDataDictionary/Model parameter?

我做错了还是应该 Html.EditorFor() 有一个额外的 ViewDataDictionary/Model 参数?

回答by Haacked

You can either create a custom ViewModel which has both properties OR you'll need to use ViewData to pass that information in.

您可以创建一个具有这两个属性的自定义 ViewModel,或者您需要使用 ViewData 来传递该信息。

回答by Graeme

I am still learning, but I had a similar problem for which I worked out a solution. My Category is an enum and I use a template control which examines the enum to determine the contents for the Select tag.

我仍在学习,但我遇到了类似的问题,为此我找到了解决方案。我的类别是一个枚举,我使用一个模板控件来检查枚举以确定 Select 标记的内容。

It is used in the view as:

它在视图中用作:

<%= Html.DropDownList
            (
            "CategoryCode",
            MvcApplication1.Utility.EditorTemplates.SelectListForEnum(typeof(WebSite.ViewData.Episode.Procedure.Category), selectedItem)
            ) %>

The enum for Category is decorated with Description attributes to be used as the text values in the Select items:

Category 的枚举用 Description 属性修饰,用作 Select 项中的文本值:

 public enum Category 
        {
            [Description("Operative")]
            Operative=1,
            [Description("Non Operative")]
            NonOperative=2,
            [Description("Therapeutic")]
            Therapeutic=3 
        }
        private Category _CategoryCode; 
        public Category CategoryCode 
        {
            get { return _CategoryCode; }
            set { _CategoryCode = value; }
        }

The SelectListForEnum constructs the list of select items using the enum definition and the index for the currently selected item, as follows:

SelectListForEnum 使用枚举定义和当前选定项的索引构造选择项列表,如下所示:

        public static SelectListItem[] SelectListForEnum(System.Type typeOfEnum, int selectedItem)
    {
        var enumValues = typeOfEnum.GetEnumValues();
        var enumNames = typeOfEnum.GetEnumNames();
        var count = enumNames.Length;
        var enumDescriptions = new string[count];
        int i = 0;
        foreach (var item in enumValues) 
        {
            var name = enumNames[i].Trim();
            var fieldInfo = item.GetType().GetField(name);
            var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            enumDescriptions[i] = (attributes.Length > 0) ? attributes[0].Description : name;
            i++;
        }
        var list = new SelectListItem[count];
        for (int index = 0; index < list.Length; index++)
        {
            list[index] = new SelectListItem { Value = enumNames[index], Text = enumDescriptions[index], Selected = (index == (selectedItem - 1)) };
        }
        return list;
    }

The end result is a nicely presented DDL.

最终结果是一个很好呈现的 DDL。

Hope this helps. Any comments about better ways to do this will be greatly appreciated.

希望这可以帮助。任何关于更好的方法的评论将不胜感激。

回答by DalSoft

Try using ViewData.ModelMetadata this contains all of your class Annotations.

尝试使用 ViewData.ModelMetadata 这包含您所有的类注释。

Excellent article http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html

优秀文章http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html