This is a migrated thread and some comments may be shown as answers.

Binding Columns to a Dictionary

3 Answers 176 Views
DataGrid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Michael
Top achievements
Rank 1
Michael asked on 04 Mar 2015, 03:12 PM
I want to do the same thing as described in http://www.telerik.com/forums/binding-to-a-dictionary, except I am using the DataGrid from UI for Windows Universal instead of UI for Silverlight.

I created a DictionaryConverter that derives from IValueConverter just as the solution in the post I linked above describes. However, when I get to build/bind the columns, I run into issues.

In the Silverlight version, the solution included an approach like:

private void BuildColumns(Layer layer)
{
  for (int i = 0; i < layer.Data[0].Attributes.Count; i++)
  {
    string key = layer.Data[0].Attributes.Keys.ElementAt(i);
    GridViewDataColumn dataColumn = new GridViewDataColumn();
    dataColumn.HeaderText = key;
    dataColumn.DataMemberBinding = PrepareDataMemberBinding(key);
    this.testGridView.Columns.Add(dataColumn);
  }
}
  
private System.Windows.Data.Binding PrepareDataMemberBinding(string key)
{
  Binding binding = new Binding();
  binding.Path = new PropertyPath("Attributes");
  binding.Converter = new DictionaryConverter(key);
  
  return binding;
}
 
public class Layer
{
  public List<LayerData> Data { get; set; }
}
 
public class LayerData
{
  public Dictionary<string, object> Attributes { get; set; }
}

However, in the Windows Universal version, I do not have a GridViewDataColumn class available. Instead, I am trying to use a DataGridTextColumn. The problem is that DataGridTextColumn does not support a DataMemberBinding property which the solution above depends on. The only way I can see of telling DataGridTextColumn which property to bind to in my row object is by assigning the PropertyName attribute. This won't work because I don't have named properties on my row objects - I'm binding to keys in a Dictionary. Is there any way to achieve this?









3 Answers, 1 is accepted

Sort by
0
Michael
Top achievements
Rank 1
answered on 04 Mar 2015, 07:29 PM
I was able to find an alternative approach that addresses this issue. I defined a custom class that derives from DataGridTextColumn, and then I wrote an override of the GetValueForInstance() method that does a lookup into my Dictionary.
0
Tsvyatko
Telerik team
answered on 06 Mar 2015, 09:45 AM
Hi Michael,

Indeed, using GetValueForInstance gives you good extension point for displaying custom data from your object.

Keep in mind that this method does not controls the operations for sorting and grouping. If you like to support them you could take advantage of delegate descriptors - http://docs.telerik.com/windows-universal/controls/raddatagrid/sorting/datagrid-delegatesortdescriptor You can set them to the corresponding columns as well as to the grid itself.

Regards,
Tsvyatko
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Michael
Top achievements
Rank 1
answered on 06 Mar 2015, 02:20 PM
Yep, I also added an override for CreateSortDescriptor() and an implementation of IKeyLookup to support custom sorting. I don't require grouping yet, so I haven't added support for that at this point. I'm posting the code I used in case anyone is interested.

public class PlaylistDataGridTextColumn : DataGridTextColumn
{
    public override object GetValueForInstance(object instance)
    {
        var cutupPlay = instance as CutupPlay;
 
        if (cutupPlay == null)
        {
            return base.GetValueForInstance(instance);
        }
             
        var header = Header.ToString();
        string metadataValue;
 
        cutupPlay.Metadata.TryGetValue(header, out metadataValue);
        return metadataValue;
    }
 
    protected override SortDescriptorBase CreateSortDescriptor()
    {
        var baseDescriptor = base.CreateSortDescriptor();
        var keyLookup = new CutupPlayMetadataKeyLookup(Header.ToString());
 
        var delegateSortDescriptor = new DelegateSortDescriptor
        {
            KeyLookup = keyLookup,
            SortOrder = baseDescriptor.SortOrder
        };
 
        return delegateSortDescriptor;
    }
}
 
public class CutupPlayMetadataKeyLookup : IKeyLookup
{
    private readonly string _metadataKey;
 
    public CutupPlayMetadataKeyLookup(string metadataKey)
    {
        _metadataKey = metadataKey;
    }
 
    public object GetKey(object instance)
    {
        var cutupPlay = (CutupPlay)instance;
        string keyValue;
 
        cutupPlay.Metadata.TryGetValue(_metadataKey, out keyValue);
 
        if (string.IsNullOrWhiteSpace(keyValue) == false)
        {
            double numericalValue;
            if (double.TryParse(keyValue, out numericalValue))
            {
                return numericalValue;
            }
        }
 
        return keyValue;
    }
}
Tags
DataGrid
Asked by
Michael
Top achievements
Rank 1
Answers by
Michael
Top achievements
Rank 1
Tsvyatko
Telerik team
Share this question
or