Dictionary Binding to ListView WPF

10,081

Solution 1

Generate your GridView columns like this:

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);
}

This will work unless your dictionary key contains special characters. The key to making this work is the indxer sytax in the binding path (the '[' and ']').

Solution 2

Create a ItemTemplate in your ListView and if you want to place both Key/Value pairs inside your listview, you could do something like this:

<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>
Share:
10,081
azamsharp
Author by

azamsharp

Mohammad Azam is an iOS Instructor at DigitalCrafts. Before joining DigitalCrafts Azam worked as a senior mobile developer at Blinds.com, A Home Depot company. Azam led the mobile team at Blinds.com to develop the Home Depot blinds/shades online experience. Previously, Azam has worked as a team lead for many large companies including Schlumberger, Baker Hughes, AIG and VALIC. Azam has also published 8-10 personal apps to the App Store, including Vegetable Tree - Gardening Guide which was featured by Apple as the best gardening app in the App Store. Azam is also active on YouTube and maintains his popular channel "AzamSharp" where he shares his iOS knowledge. Azam is also a Udemy instructor where he has published courses on "Swift 2.0" and "iOS MapKit Development Using Swift Language". Azam also frequently contributes iOS articles to the Code Magazine and talks at different iOS conferences all around the country. Before entering the iOS community Azam was an active member of the Microsoft .NET community. Azam was also awarded Microsoft MVP award due to his contributions in the .NET community. Azam is also an instructor on Udemy with more than 2000 students. Azam has earned perfect ratings for his courses on Udemy. You can check out Azam's courses using the link below: http://www.azamsharp.com/courses/ When not developing iOS applications Azam likes to spend time with his family and plan his next trip to the unknown corners of the world.

Updated on June 04, 2022

Comments

  • azamsharp
    azamsharp almost 2 years

    I have a List which contains Dictionary items. This means

    List[0] = Dictionary Item => Item[0] = id, Item[1] = Name, Item[2] = Amount.

    I need to show this in a ListView control in a Grid manner. The dictionary can vary.

    UPDATE:

    Each Item in the List looks like this:

    ["_id"] = "11212131" ["Title"] = "this is title" ["DateCreated"] = "some date"

    The items inside the dictionary can be different.

    UPDATE 2:

    I am using the following code to create a dynamic Gridview control and then add the columns into the GridView control. It works but now there is a long horizontal line of same repeative columns. I need to display the column name and under that the data that belongs to that column.

      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; 
    

    UPDATE 3:

    I am pretty close. It works but it displays only a long single row with repeated columns.

     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;