Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind an 2D array bool[][] to a WPF DataGrid (one-way)?

I have a matrix kind datagrid like this.

enter image description here

this grid is designed entirely in XAML

Now how to insert values into these datagridcell with 2 dimensional array ? the values which is needed to be inserted must be of bool datatype (either TRUE or FALSE). Any ideas ?

like image 612
Indhi Avatar asked May 29 '13 10:05

Indhi


1 Answers

Here is my approach for a MVVM scenario, using a converter which creates a DataView which can be bound to the grids ItemsSource. It's for a special Matrix datatype which holds doubles, but you'll be able to modify it yourself for your requirements:

public class MatrixToDataViewConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var array = value as Matrix;
        if (array == null) return null;

        //var array = ILMath.rand(3, 5);

        var rows = array.Dimensions[0];
        var columns = array.Dimensions[1];

        var t = new DataTable();
        for (var c = 0; c < columns; c++)
        {
            t.Columns.Add(new DataColumn(c.ToString()));
        }

        for (var r = 0; r < rows; r++)
        {
            var newRow = t.NewRow();
            for (var c = 0; c < columns; c++)
            {
                var v = array[r, c];

                // Round if parameter is set
                if (parameter != null)
                {
                    int digits;
                    if (int.TryParse(parameter.ToString(), out digits))
                        v = Math.Round(v, digits);
                }

                newRow[c] = v;
            }

            t.Rows.Add(newRow);
        }


        return t.DefaultView;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Define a resource for the converter:

<converter:MatrixToDataViewConverter x:Key="MatrixToDataViewConverter" />

And use it like this:

<DataGrid ItemsSource="{Binding Matrix, Converter={StaticResource MatrixToDataViewConverter}, ConverterParameter=1}"/>

It doesn't allow two way binding, though...

EDIT

Here's the version for an array bool[][]:

public class BoolArrayToDataViewConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var array = value as bool[,];
        if (array == null) return null;

        var rows = array.GetLength(0);
        if (rows == 0) return null;

        var columns = array.GetLength(1);
        if (columns == 0) return null;

        var t = new DataTable();

        // Add columns with name "0", "1", "2", ...
        for (var c = 0; c < columns; c++)
        {
            t.Columns.Add(new DataColumn(c.ToString()));
        }

        // Add data to DataTable
        for (var r = 0; r < rows; r++)
        {
            var newRow = t.NewRow();
            for (var c = 0; c < columns; c++)
            {
                newRow[c] = array[r, c];
            }
            t.Rows.Add(newRow);
        }

        return t.DefaultView;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and the usage:

<DataGrid ItemsSource="{Binding Matrix, Converter={StaticResource BoolArrayToDataViewConverter}}"/>

And this is what it looks like in the very raw version. You can then style the DataGrid and edit it's templates, but this is another question...

UI

like image 177
Marc Avatar answered Oct 01 '22 10:10

Marc