我想创建一个抽象类和一个模板编辑器来生成所需的html。
我的问题是:如何使用子类中的属性DisplayName?如果它存在,它总是使用抽象类属性。
以下是我的班级:
public abstract class DropDownViewModel
{
public virtual string SelectedId { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
public class UsersDropDown : DropDownViewModel
{
[DisplayName("Users")]
public override string SelectedId { get; set; }
}
这是我的模板:
@model DropDownViewModel
@Html.LabelFor(x => x.SelectedId)
@Html.DropDownListFor(
x => x.SelectedId,
new SelectList(Model.Items, "Value", "Text", Model.SelectedId)
)
任何帮助都将不胜感激。
答案 0 :(得分:1)
您的模板是为DropDownViewModel
类型定义的,因此MVC将查看该类中的属性。您可以为每个派生类定义不同的模板,但这会破坏模板的用途(除非您计划为每个子类生成不同的html,在这种情况下,只需为每个派生类创建一个模板,您应该使用正确的属性!)。
一种解决方案是在视图模型中设置具有下拉属性的DisplayName
属性,如下所示:
public class YourViewModel
{
[DisplayName("Users")]
public DropDownViewModel UsersDropDown { get; set; }
}
然后将@Html.LabelFor
移动到渲染视图模型的视图,在下拉模板之外。
@*Main view rendering the whole view model*@
@model YourViewModel
....
@Html.LabelFor(m=> m.DropDown)
@Html.EditorFor(m=> m.DropDown)
@*DropDownViewModel editor template*@
@model DropDownViewModel
@Html.DropDownListFor(
x => x.SelectedId,
new SelectList(Model.Items, "Value", "Text", Model.SelectedId)
)
使用这种方法,您不需要DropDownViewModel
的多个子类,并且持有下拉列表的模型负责标签名称(如果您需要在另一个标签文本的不同上下文中使用“用户”下拉菜单,该怎么办?说得通?)。请注意,您可以使用具有DisplayName属性的常量或资源,因此您无需在具有用户下拉列表的每个模型上对标签文本进行硬编码。
如果您需要/更喜欢将标签文本保留在编辑器模板中,那么您只需在DropDownViewModel类中为标签文本添加字符串属性即可。
public abstract class DropDownViewModel
{
public string SelectedId { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
public abstract string LabelText { get; }
}
public class UsersDropDown : DropDownViewModel
{
public override string LabelText { get { return "Users"; } }
}
然后使用该属性将标签文本传递给编辑器模板的@Html.LabelFor
方法:
@model MvcApplication1.Models.DropDownViewModel
@Html.LabelFor(m => m.SelectedId, Model.LabelText)
@Html.DropDownListFor(
x => x.SelectedId,
new SelectList(Model.Items, "Value", "Text", Model.SelectedId)
)
请注意,使用此方法,每个下拉列表都需要一个派生类,但如果向属性添加setter,则至少包含这些下拉列表的模型可以指定标签文本。
希望有所帮助!