Search code examples
wpfdata-bindingwpfdatagrid

How to Bind a Dictionary with the Key value being a Binding Property in WPF?


I have a class like this:

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int AccountId { get; set; }
    public Dictionary<int, List<string>> Values { get; set; }
}

I have a DataGrid in my XAML where I want to display the first index of the List<string> within the dictionary property Values as one of the column values, where the key being passed in will be the AccountId. The ItemSource of my DataGrid is a list of Person objects coming from my ViewModel, and the DataGrid has 3 columns, PersonId, Name, and Value (where value is the first index of the List<string> collection in the dictionary item)

I have seen examples on stackoverflow and other places on the internet that try to do this but none of the solutions worked for me.

Here is my XAML code:

<DataGrid Name="MyDataGrid" ItemsSource="{Binding Persons}">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="ID">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding PersonId}" IsEnabled="False" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Name">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Name}" IsEnabled="False" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Value">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Values[{Binding AccountId}][0]}" IsEnabled="False" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

The last column is the column where I try to use a {Binding} as the key value, but it does not work. If I hard-code a valid AccountId, it works. Has anyone encountered this before?

Thanks!


Solution

  • one of view model purposes is to provide data to view in a convenient format. code to get value from dictionary by key and then return first item can be written in a view model, not in converter:

    public class Person
    {
        public int PersonId { get; set; }
        public string Name { get; set; }
        public int AccountId { get; set; }
        public Dictionary<int, List<string>> Values { get; set; }
    
        public string AccountIdValue { get { return Values[AccountId].FirstOrDefault(); } }
    }
    

    then bind to that helper property:

    <TextBox Text="{Binding AccountIdValue}" IsEnabled="False" />