【发布时间】:2016-04-02 15:41:56
【问题描述】:
我目前正在我的 ASP.NET MVC 项目中实现一个家谱系统。为了设置家庭成员之间的关系,我需要每行显示两个 ComboBox/DropDownList 来定义从一个成员到另一个成员的关系。
首先我将分享我的代码,然后我将解释到目前为止我尝试了哪些方法以及最后的结果。
视图模型
public class FamilyTreeRelationshipViewModel
{
[ScaffoldColumn(false)]
public string FromMemberId { get; set; }
[ScaffoldColumn(false)]
public string ToMemberId { get; set; }
public Member FromMember { get; set; }
public IEnumerable<Member> ToMembers { get; set; }
[UIHint("FTComboBox")]
[AdditionalMetadata("BindTo", "relationships")]
[Required]
[Display(Name = "From Relationship")]
public string FromRelationship { get; set; }
[UIHint("FTComboBox")]
[AdditionalMetadata("BindTo", "relationships")]
[Required]
[Display(Name = "To Relationship")]
public string ToRelationship { get; set; }
}
控制器
public class FamilyTreeController : Controller
{
private AppMVC db = new AppMVC();
public ActionResult Index(Guid? cid, Guid? mid)
{
if (cid == null && mid == null)
{
return new HttpStatusCodeResult(HttpStatusCode.NotFound);
}
var frommember = db.Member.FirstOrDefault(x => x.MemberId == mid && x.CaseId == cid && x.Deleted == false);
var tomembers = db.Member.Where(x => x.CaseId == cid && x.MemberId != mid.Value && x.Deleted == false).ToList();
ViewBag.cid = cid;
ViewBag.mid = mid;
PopulateRelationship();
var familyTreeRelationshipViewModel = new FamilyTreeRelationshipViewModel
{
FromMember = frommember,
ToMembers = tomembers,
};
return View(familyTreeRelationshipViewModel);
}
public void PopulateRelationship()
{
var relationship = db.RelationshipDD
.Where(c => c.Deleted == false && c.Code != "PA")
.OrderBy(c => c.OrderIndex)
.Select(c => new RelationshipDDViewModel
{
Code = c.Code,
Definition = c.Definition
})
.ToList();
ViewData["relationships"] = relationship;
}
}
组合框的编辑器模板
@model object
@{
var bindto = ViewData.ModelMetadata.AdditionalValues["BindTo"].ToString();
var fieldname = ViewData.ModelMetadata.PropertyName;
var prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
}
@(Html.Kendo().ComboBoxFor(m => m)
.Filter("contains")
.Placeholder(ViewData.ModelMetadata.DisplayName)
.DataTextField("Definition")
.DataValueField("Code")
.HtmlAttributes(new { style = "width: 100%", Id = prefix})
.BindTo((System.Collections.IEnumerable)ViewData[bindto])
)
@Html.ValidationMessageFor(m => m, "", new { @class = "mdc-text-red-400" })
为了给每一行显示一个新的结果,我在 View 中使用了 foreach:
@if (Model.ToMembers != null)
{
if (Model.ToMembers.Any())
{
foreach (var othermembers in Model.ToMembers.OrderBy(x => x.MemberNumberSuffix))
{
@Html.EditorFor(m => m.ToRelationship)
@Html.EditorFor(m => m.FromRelationship)
}
}
}
正如您在下面的屏幕截图中看到的,仅渲染了第一行中的 ComboBox。我认为这是因为每个 ComboBox 的控件 ID 相同。我检查了浏览器开发者工具(F12),它们都有相同的 ID。
后来我想我应该使用 For 而不是 Foreach 看看会发生什么:
@if (Model.ToMembers != null)
{
if (Model.ToMembers.Any())
{
for (var i = 0; i < Model.ToMembers.Count(); i++)
{
var othermembers = Model.ToMembers.ToList()[i];
@Html.EditorFor(m => m.ToRelationship[i])
@Html.EditorFor(m => m.FromRelationship[i])
}
}
}
正如您在下面的屏幕截图中看到的,所有 ComboBox 都消失了,所有内容都呈现为 Char。这里唯一的区别是每个控件/输入都有自己的 Id,这很好,但不像我预期的那样好。
毕竟,我决定为此目的使用内置 DropDownList (MVC),结果是一样的。因为我认为 Telerik 控件有问题。
我什至尝试直接在 View 内部使用 ComboBox 而不是 EditorFor,结果不一样。每一行都是单独成功渲染的,但它又是 Char 类型,甚至错误消息也这么说。通常它应该说,“来自关系字段是必需的”。
@if (Model.ToMembers != null)
{
if (Model.ToMembers.Any())
{
for (var i = 0; i < Model.ToMembers.Count(); i++)
{
@(Html.Kendo().ComboBoxFor(m => m.ToRelationship[i])
.Filter("contains")
.Placeholder(ViewData.ModelMetadata.DisplayName)
.DataTextField("Definition")
.DataValueField("Code")
.HtmlAttributes(new { style = "width: 100%" })
.BindTo((System.Collections.IEnumerable)ViewData["relationships"])
)
@(Html.Kendo().ComboBoxFor(m => m.FromRelationship[i])
.Filter("contains")
.Placeholder(ViewData.ModelMetadata.DisplayName)
.DataTextField("Definition")
.DataValueField("Code")
.HtmlAttributes(new { style = "width: 100%" })
.BindTo((System.Collections.IEnumerable)ViewData["relationships"])
)
}
}
}
问题
- 为什么我不能为此目的使用 EditorFor?
- 为什么类型已更改为 Char,我该如何解决?
- 还有其他方法可以实现这一点吗?
提前感谢您的帮助!
【问题讨论】:
-
这里有很多奇怪的代码,很难理解你想做什么。您不能使用
for循环为集合生成控件(您需要for循环或自定义EditorTemplate),但您没有创建与集合关联的任何内容(您拥有的唯一集合是属性ToMembers,而您下拉菜单与此无关)。Char错误的原因是FromRelationship和ToRelationship是字符串,所以FromRelationship[i]是字符串中的一个字符(Char)。 -
您的视图模型对您显示的图像毫无意义(您的下拉菜单也没有),但我无法理解您想要实现的目标。
-
@StephenMuecke 感谢您的评论。我需要执行以下操作:每一行/结果都应该有它自己的 ComboBox 和它的唯一 ID,以便我可以将用户的关系从一个成员映射到另一个成员。关于集合,我通过 ViewData 从控制器获取关系值。
-
id与它无关(除了是无效的 html 并且如果您有 javascript 引用它们,它将不起作用)。它的name属性很重要(使用foreach循环它们都是相同的)。我已经阅读了大约 10 次,但仍然无法理解您在做什么:) -
当然。看起来你有一个人罗杰莫里斯,你想与其他人建立关系? (在这种情况下,您的模型不正确)
标签: c# asp.net asp.net-mvc razor telerik