字典绑定到 ListView WPF
Posted
技术标签:
【中文标题】字典绑定到 ListView WPF【英文标题】:Dictionary Binding to ListView WPF 【发布时间】:2011-01-23 10:25:41 【问题描述】:我有一个包含字典项目的列表。这意味着
List[0] = Dictionary Item => Item[0] = id,Item[1] = 名称,Item[2] = 金额。
我需要以网格的方式在 ListView 控件中显示它。字典可能会有所不同。
更新:
列表中的每个项目如下所示:
["_id"] = "11212131" ["标题"] = "这是标题" ["DateCreated"] = "某个日期"
字典中的项目可以不同。
更新 2:
我正在使用以下代码创建一个动态 Gridview 控件,然后将列添加到 GridView 控件中。它可以工作,但现在有一条长长的水平线,由相同的重复列组成。我需要显示列名以及属于该列的数据。
var gridview = new GridView();
foreach (var o in objs)
var dic = o as Dictionary<String, Object>;
var enumerator = dic.GetEnumerator();
while (enumerator.MoveNext())
var current = enumerator.Current;
var gridViewColumn = new GridViewColumn();
gridViewColumn.Header = current.Key;
var binding = new Binding(current.Key);
//binding.Source = current;
gridViewColumn.DisplayMemberBinding = binding;
gridview.Columns.Add(gridViewColumn);
// new row
lvCollections.View = gridview;
更新 3:
我很接近。它可以工作,但它只显示一个带有重复列的长单行。
var gridview = new GridView();
foreach (var o in objs)
var dic = o as Dictionary<String, Object>;
var enumerator = dic.GetEnumerator();
while (enumerator.MoveNext())
var gridViewColumn = new GridViewColumn();
var current = enumerator.Current;
gridViewColumn.Header = current.Key;
var binding = new Binding();
binding.Source = current;
binding.Path = new PropertyPath("Value");
gridViewColumn.DisplayMemberBinding = binding;
gridview.Columns.Add(gridViewColumn);
// new row
lvCollections.ItemsSource = objs;
lvCollections.View = gridview;
【问题讨论】:
我绝对理解这个想法,但是您能否发布您的课程以便我们了解底层数据是如何受到约束的? 没有固定的班级。对象被序列化,然后反序列化为字典类型。 【参考方案1】:像这样生成您的 GridView 列:
public void OnDataContextChanged(...)
var distinctKeys = (
from dict in (List<Dictionary<string,object>>)DataContext
from key in dict.Keys
select key
).Distinct();
gridView.Columns.ReplaceWith(
from key in distinctKeys
orderby key
select new GridViewColumn
Header = key,
DisplayMemberBinding = new Binding("[" + key + "]"),
);
// The above code uses an extension method like this
static void ReplaceWith<T>(this ObserableCollection<T> collection, IEnumerable<T> newItems)
collection.Clear();
foreach(var item in newItems)
collection.Add(item);
除非您的字典键包含特殊字符,否则这将起作用。完成这项工作的关键是绑定路径中的索引器语法('[' 和 ']')。
【讨论】:
太棒了!我不知道关键语法。谢谢一百万 :) 这就像一个魅力。 如何在 XAML 中做索引器? 要在 XAML 中使用索引器语法,只需在绑定路径中使用 [],例如。Content="Binding [KeyGoesHere]"
,或者如果你想索引一个属性,Content="Binding DictionaryProperty[KeyGoesHere]"
如果密钥是动态的,解决此问题的规范方法是使用 MultiBinding 和 IMultiValueConverter。在 MultiBinding 中,第一个 Binding 找到要索引的对象,第二个 Binding 找到要使用的键。 IMultiValueConverter 的主体类似于var dict = (Dictionary<K,V>)values[0]; var key = (K)values[1]; return dict[key];
【参考方案2】:
你需要的是一个像 ObservableCollection 这样的 ObservableDictionary, 查看此线程以查看一些提示http://social.msdn.microsoft.com/forums/en-US/wpf/thread/af80921b-8bf0-4763-bd30-1e01dfc6f132/
这是给你的答案 - http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
我认为在后面的代码中创建 UIElements 并动态添加到 VisualTree 并不是一个更好的主意。尝试使用 ObservableDictionary 进行纯数据绑定,它会在内部创建您的 GridView 数据模板,并使您的 ListView 保持正确的列顺序。
避免 gridview.Columns.Add(gridViewColumn);在循环。它清楚地创建了等于行数的列。当然,我不清楚您的 DynamicDictionary Schema..
【讨论】:
我不想使用 ObservableDictionary,因为我无意观看或观察它们。 数据结构有点复杂。我有一个 List【参考方案3】:在你的 ListView 中创建一个 ItemTemplate,如果你想在你的 listview 中放置两个键/值对,你可以这样做:
<ListBox ItemsSource="Binding Source=StaticResource YourDataObject">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="Binding Key" />
<TextBlock xml:space="preserve"></TextBlock>
<Label Content="Binding Value" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
【讨论】:
上面的代码只显示第一个键是“id”和“id”的值是“22121231”。似乎我需要动态地执行此操作。以上是关于字典绑定到 ListView WPF的主要内容,如果未能解决你的问题,请参考以下文章
如何将listview项绑定绑定到页面的Viewmodel?
MVVM 绑定 ObservableCollection 到 Listview 不工作
c#wpf将列表绑定到Listview - listview行为空[关闭]