Alex Rivera | Logout

How to populate a WPF grid based on a 2-dimensional array

Asked 2008-11-10T01:05:52.257
59

I have a 2-dimensional array of objects and I basically want to databind each one to a cell in a WPF grid. Currently I have this working but I am doing most of it procedurally. I create the correct number of row and column definitions, then I loop through the cells and create the controls and set up the correct bindings for each one.

At a minimum I would like to be able to use a template to specify the controls and bindings in xaml. Ideally I would like to get rid of the procedural code and just do it all with databinding, but I'm not sure that's possible.

Here is the code I am currently using:

public void BindGrid()
{
    m_Grid.Children.Clear();
    m_Grid.ColumnDefinitions.Clear();
    m_Grid.RowDefinitions.Clear();

    for (int x = 0; x < MefGrid.Width; x++)
    {
        m_Grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star), });
    }

    for (int y = 0; y < MefGrid.Height; y++)
    {
        m_Grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star), });
    }

    for (int x = 0; x < MefGrid.Width; x++)
    {
        for (int y = 0; y < MefGrid.Height; y++)
        {
            Cell cell = (Cell)MefGrid[x, y];                    

            SolidColorBrush brush = new SolidColorBrush();

            var binding = new Binding("On");
            binding.Converter = new BoolColorConverter();
            binding.Mode = BindingMode.OneWay;

            BindingOperations.SetBinding(brush, SolidColorBrush.ColorProperty, binding);

            var rect = new Rectangle();
            rect.DataContext = cell;
            rect.Fill = brush;
            rect.SetValue(Grid.RowProperty, y);
            rect.SetValue(Grid.ColumnProperty, x);
            m_Grid.Children.Add(rect);
        }
    }

}
Edit
Report

1 Answer

45

Here is a Control called DataGrid2D that can be populated based on a 2D or
1D array (or anything that implements the IList interface). It subclasses DataGrid and adds a property called ItemsSource2D which is used for binding against 2D or 1D sources. Library can be downloaded here and source code can be downloaded here.

To use it just add a reference to DataGrid2DLibrary.dll, add this namespace

xmlns:dg2d="clr-namespace:DataGrid2DLibrary;assembly=DataGrid2DLibrary"

and then create a DataGrid2D and bind it to your IList, 2D array or 1D array like this

<dg2d:DataGrid2D Name="dataGrid2D"
                 ItemsSource2D="{Binding Int2DList}"/>

enter image description here


OLD POST
Here is an implementation that can bind a 2D array to the WPF datagrid.

Say we have this 2D array

private int[,] m_intArray = new int[5, 5];
...
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        m_intArray[i,j] = (i * 10 + j);
    }
}

And then we want to bind this 2D array to the WPF DataGrid and the changes we make shall be reflected in the array. To do this I used Eric Lippert's Ref class from this thread.

public class Ref<T>  
{ 
    private readonly Func<T> getter;  
    private readonly Action<T> setter; 
    public Ref(Func<T> getter, Action<T> setter)  
    {  
        this.getter = getter;  
        this.setter = setter;  
    } 
    public T Value { get {
answered 2010-10-23T04:02:04.203

Your Answer