Search code examples
c#arrayswpfxamldatagrid

Binding matrix arrays to WPF DataGrid


I have 3 string arrays like this:

public string[] RowHeaders
{
    get { return new[] {"RowHeader1", "RowHeader2", "RowHeader3", "RowHeader4"}; 
}

public string[] ColumnHeaders
{
    get { return new[] {"ColumnHeader1", "ColumnHeader2", "ColumnHeader3"}; }
}

public string[][] Values
{
    get { return new[]
    {
        new []{"Value11", "Value12", "Value13"},
        new []{"Value21", "Value22", "Value23"},
        new []{"Value31", "Value32", "Value33"},
        new []{"Value41", "Value42", "Value43"},
    }; }
}

Array sizes are unknown until run-time (array values in code snippet are for showing the concept). I want to create a WPF grid from them like

Grid with array data

which binds to these 3 arrays and designed entirely in XAML (if possible). How?


Solution

  • here a solution using DataTable and MultipleBinding, in the xaml pass the three arrays to an IMultivaluesConverter:

    <Grid>
       <DataGrid>
            <DataGrid.ItemsSource>
                <MultiBinding Converter="{StaticResource MatrixToDataViewConverter}">
                    <Binding Path="ColumnHeaders"/>
                    <Binding Path="RowHeaders"/>
                    <Binding Path="Values"/>
                </MultiBinding>
            </DataGrid.ItemsSource>
        </DataGrid>
    </Grid>
    

    then in the converter manage those arrays to create a DataView that will be bond to the Grid ItemSource :

     public class MatrixToDataViewConverter:IMultiValueConverter
    {            
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var myDataTable = new DataTable();
            var colums = values[0] as string[];
            var rows = values[1] as string[];
            var vals = values[2] as string[][];
            myDataTable.Columns.Add("---");    //The blanc corner column
            foreach (var value in colums)
            {
                myDataTable.Columns.Add(value);
            }
            int index = 0;
    
            foreach (string row in rows)
            {
                var tmp = new string[1 + vals[index].Count()];                
                vals[index].CopyTo(tmp, 1);
                tmp[0] = row;
                myDataTable.Rows.Add(tmp);
                index++;
            }     
            return myDataTable.DefaultView;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    output : enter image description here