我问这个问题,因为即使我已经读了很多ListView资源,我仍然没有“得到”它。
我有一堆Foo
有一个与它们相关的项目列表(称为Bar
),并且将它们从数据访问/业务逻辑层作为包含Foo及其关联的bar
的Dictionary拖动。 我想连接在网页上的这些项目到一个ListView
,左侧保存Foo.Name
,并在下拉列表中右侧的List <Bar>
。 (下面用ASCII展示):
------------------------------------------------------------------
| Name Of Item | DropDownList (of List<T>) |
|---------------------------------| _____________________ |
| foo1 | | bar1 | v | |
| | |_______________|___| |
------------------------------------------------------------------
| | DropDownList (of List<T>) |
| | _____________________ |
| foo2 | | bar2 | v | |
| | |_______________|___| |
------------------------------------------------------------------
这是一个ListView; 这些项目从一个数据库被拉到Dictionary <Foo,List <Bar>
。 我试图让dictionary中的键值显示在“项目名称”下,并试图让List <T> Bar显示为ListView右侧的DropDownList。
----------------- -----------------
| Foo | | Bar |
----------------- -----------------
| Id | | ItemName |
| Name | | ItemValue |
| BarID | | |
----------------- -----------------
所以要回顾一下,我想将Dictionary.Key“Name”放置在ListView的左侧,而Dictionary.Value(恰好是一个列表)放到右侧的DropdownList中。
因此,对于每个键/值对,都会有一个名称和一个下拉列表来存放每个键的值。
但是我遇到了问题,希望有人能告诉我我做错了什么。
protected Dictionary<Foo, List<Bar>> FooDictionary
{
get;
set;
}
protected void DataBindFooList(List<int> SelectedFoos)
{
System.Web.UI.WebControls.ListView lv = lvFooList;
try
{
Dictionary<Foo, List<Bar>> fooDictionary =
new Dictionary<Foo, List<Bar>>();
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);
}
<asp:ListView ID="lvFooList" runat="server">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemSeparatorTemplate>
<hr />
</ItemSeparatorTemplate>
<ItemTemplate>
<%#Eval("Name") %>
<asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:ListView>
发布于 2018-02-20 12:13:47
你的问题出现了,因为在DataBindFooList()中绑定ddlListOfBars没有意义,因为不只有一个DropDownList可以绑定到数据绑定。 当你调用lv.DataBind()时,ListView会为每个Foo创建一个ItemTemplate的副本,每个副本都包含一个ddlListOfBars。 您需要告诉它将每个DropDownList绑定到正确的List <Bar>。 你可以通过设置ddlListOfBars的数据源,而不是在后面的代码中做到这一点:
<ItemTemplate>
<%#Eval("Key.Name") %>
<asp:DropDownList
ID="ddlListOfBars"
runat="server"
DataSource='<%#Eval("Value")%>'
DataValueField="ItemValue"
DataTextField="ItemName" />
</ItemTemplate>
请注意,还需要使用“Key.Name”来获取Foo的name属性。 要绑定的单个字典项是KeyValuePair <Foo,List <Bar>,它具有分别访问Foo和List <Bar>的Key属性和Value属性。
如果你在ItemTemplate中有很多东西,那么将内容移出到用户控件中会很有用。 用户控件可以有一个强类型的属性来访问DataItem,并且具有对其子控件的强类型访问。 这样就可以在没有所有Cast和FindControl()噪声的情况下获得ItemDataBound事件的灵活性。 我怀疑在这种情况下我会打扰,但它会像这样
<asp:ListView ID="lvFooList" runat="server">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemSeparatorTemplate>
<hr />
</ItemSeparatorTemplate>
<ItemTemplate>
<uc:ListViewContents DataItem='<%# Container.DataItem %>' />
</ItemTemplate>
ListViewContents.ascx..
<asp:Label ID="lbName" runat="server"/>
<asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
ListViewContents.ascx.cs..。
public KeyValuePair<Foo,List<Bar>> 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();
}
发布于 2018-02-20 13:07:22
就像你想要的那样:
<asp:ListView ID="lvFooList" runat="server">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemSeparatorTemplate>
<hr />
</ItemSeparatorTemplate>
<ItemTemplate>
<asp:Label ID="lbName" runat="server"/>
<asp:DropDownList ID="ddlListOfBars" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:ListView>
然后我写了一个非常快速的测试
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<Bar>()
{
new Bar() {ItemName = "bar1", ItemValue = "barV1"},
new Bar() {ItemName = "bar2", ItemValue = "barV2"}
};
var fooKey2 = new Foo() {Name = "foo2"};
var barList2 = new List<Bar>()
{
new Bar() {ItemName = "bar3", ItemValue = "barV3"},
new Bar() {ItemName = "bar4", ItemValue = "barV4"}
};
var dicFooBar = new Dictionary<Foo, List<Bar>>() {{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<Foo, List<Bar>>)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();
}
似乎做你想做的,但我的代码只是快速测试代码,所以请注意。不过,它确实呈现出了预期的效果。
https://stackoverflow.com/questions/-100007400
复制相似问题