【问题标题】:Dictionary Binding to ListView WPF字典绑定到 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; 

【问题讨论】:

  • 我绝对理解这个想法,但是您能否发布您的课程以便我们了解底层数据是如何受到约束的?
  • 没有固定的班级。对象被序列化,然后反序列化为字典类型。

标签: wpf listview binding


【解决方案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”。似乎我需要动态地执行此操作。
猜你喜欢
  • 2016-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 2011-01-14
  • 2011-03-27
  • 2015-10-28
  • 1970-01-01
相关资源
最近更新 更多