ASP.NET中List 和ListViews的Dictionary
前言
我问这个问题,因为即使我已经阅读了很多ListView资源,我仍然没有“得到”它。
背景
我有一堆Foo
有一个与它们相关的项目列表( 称为 Bar
),我将它们从数据访问/业务逻辑层中拉出来作为包含Foo
及其相关Bars
Dictionary。 我想在网页上将这些项目吐出到一个ListView
,该ListView
包含左侧的Foo.Name
,右侧的List
位于下拉列表中。 (以下面我美丽的ASCII艺术所示):
列表显示
-------------------------------------------------- ---------------- | 物品名称| DropDownList(List )| | --------------------------------- | _____________________ | | foo1 | | bar1 | v | | | | | _______________ | ___ | | -------------------------------------------------- ---------------- | | DropDownList(List )| | | _____________________ | | foo2 | | bar2 | v | | | | | _______________ | ___ | | -------------------------------------------------- ----------------
好吧,这是正在发生的事情。 这是一个ListView; 这些项目从数据库中拉入Dictionary<Foo, List>
。 我试图从字典中获取Key Value以显示在“Name of Item”下,并且我试图让`List Bar’在ListView的右侧显示为DropDownList。
类图
----------------- ----------------- | Foo | | 酒吧| ----------------- ----------------- | Id | | ItemName | | 名称| | ItemValue | | BarID | | | ----------------- -----------------
所以回顾一下,我想把Dictionary.Key“Name”放在ListView的左侧,将Dictionary.Value(恰好是一个列表)放到右侧的DropdownList中。
因此,对于每个Key / Value对,都会有一个Name和一个下拉列表来存放每个Key的Value。
但是我遇到了问题(显然),我希望有人可以告诉我我做错了什么。
代码背后:
protected Dictionary<Foo, List> FooDictionary { get; set; } protected void DataBindFooList(List SelectedFoos) { System.Web.UI.WebControls.ListView lv = lvFooList; try { Dictionary<Foo, List> fooDictionary = new Dictionary<Foo, List>(); foreach (int Foo in SelectedFoos) { // Build List of Foos to add as Dictionary.Keys fooDictionary.Add(fooScalar, Bar) } FooDictionary = fooDictionary; lv.DataSource = FooDictionary; lv.DataBind(); ddlListOfBars.DataSource = FooDictionary; ddlListOfBars.DataValueField = "ItemValue"; ddlListOfBars.DataTextField = "ItemName"; ddlListOfBars.DataBind(); } catch (Exception ex) { SetMessage(divFooMsg, "Unable to retrieve Foos: " + ex.Message, true, true); }
ListView代码:
问题:
- 是否可以这样使用词典?
- 关于我出错的地方的任何指示? (资源,提示等会有所帮助)
- 有一个更好的方法吗?
- 如果这个问题显然是泥,请发表评论,以便我可以弄清楚如何改进它。
您的问题出现是因为在DataBindFooList()中数据绑定ddlListOfBars没有意义,因为数据绑定不只有一个DropDownList。 当您调用lv.DataBind()时,ListView会为每个Foo创建一个ItemTemplate副本,每个Foo包含一个ddlListOfBars。 您需要告诉它将每个DropDownList绑定到正确的List
<%#Eval("Key.Name") %>
请注意,您还需要使用“Key.Name”来获取Foo的name属性。 您绑定的各个字典项是KeyValuePair
编辑
如果你在ItemTemplate中有很多事情,那么将内容移到用户控件中会很有用。 用户控件可以具有强类型属性来访问DataItem,并且具有对其子控件的强类型访问。 这样就可以获得ItemDataBound事件的灵活性,而不会产生所有的转换和FindControl()噪声。 我怀疑在这种情况下我会烦恼,但它会有类似的东西
ListViewContents.ascx …
ListViewContents.ascx.cs …
public KeyValuePair> DataItem { get; set; } protected override void OnDataBinding(EventArgs e) { base.OnDataBinding(e); lbName.Text = DataItem.Key.Name; ddlListOfBars.DataTextField = "ItemName"; ddlListOfBars.DataValueField = "ItemValue"; ddlListOfBars.DataSource = DataItem.Value; ddlListOfBars.DataBind(); }
这是你想要的东西:
然后我写了一个非常快速讨厌的测试
public class Foo { public string Name; } public class Bar { public string ItemName { get; set; } public string ItemValue { get; set; } } protected void Page_Load(object sender, EventArgs e) { var fooKey1 = new Foo() {Name = "foo1"}; var barList1 = new List() { new Bar() {ItemName = "bar1", ItemValue = "barV1"}, new Bar() {ItemName = "bar2", ItemValue = "barV2"} }; var fooKey2 = new Foo() {Name = "foo2"}; var barList2 = new List () { new Bar() {ItemName = "bar3", ItemValue = "barV3"}, new Bar() {ItemName = "bar4", ItemValue = "barV4"} }; var dicFooBar = new Dictionary>() {{fooKey1, barList1}, {fooKey2, barList2}}; lvFooList.ItemDataBound += lvFooList_ItemDataBound; lvFooList.DataSource = dicFooBar; lvFooList.DataBind(); } void lvFooList_ItemDataBound(object sender, ListViewItemEventArgs e) { var dataItem = (ListViewDataItem)e.Item; var fooBarList = (KeyValuePair>)dataItem.DataItem; ((Label) dataItem.FindControl("lbName")).Text = fooBarList.Key.Name; var ddlListOfBars = (DropDownList) dataItem.FindControl("ddlListOfBars"); ddlListOfBars.DataTextField = "ItemName"; ddlListOfBars.DataValueField = "ItemValue"; ddlListOfBars.DataSource = fooBarList.Value; ddlListOfBars.DataBind(); }
似乎做你想做的,但我的代码只是快速测试代码,所以要警告。 它确实按预期渲染。