字典绑定到 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 找到要使用的键。 IMul​​tiValueConverter 的主体类似于var dict = (Dictionary&lt;K,V&gt;)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 objs,然后每个对象都是一个字典,它有 6-7 个键。每个键都是列的名称。【参考方案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项和标题绑定字典

如何将listview项绑定绑定到页面的Viewmodel?

MVVM 绑定 ObservableCollection 到 Listview 不工作

c#wpf将列表绑定到Listview - listview行为空[关闭]

将 ListView 的 SelectedItems 绑定到 ViewModel

绑定到 ListView 的 SelectedItem 属性时设置初始选定项