Search code examples
.netwpfdatagridvalueconverter

How can I display array elements in a WPF DataGrid?


I'm trying to display a series of rows in a WPF DataGrid where each row contains an array of booleans (the number of which is the same for all rows, it's not a jagged 2D array) that I want to display as individual columns, eg.

Name            | Day 1 | Day 2 | Day 3 | Day 4 | Day 5 | Day 6 |
-----------------------------------------------------------------
Bring out Trash |   X   |       |   X   |       |       |   X   |
Pay Bills       |       |       |       |       |   X   |       |
Commit Suicide  |       |       |       |       |       |   X   |

Currently, I'm using this class for my DataGrid rows:

private class GridRow {
  public string Name { get; set; }
  public char Day1 { get; set; }
  public char Day2 { get; set; }
  public char Day3 { get; set; }
  public char Day4 { get; set; }
  public char Day5 { get; set; }
  public char Day6 { get; set; }
  public char Day7 { get; set; }
  public char Day8 { get; set; }
  public char Day9 { get; set; }
}

In the real world case, make that 128 booleans. It gets the job done for the time being (for as long as nobody creates cyclic plans with a length over 128 days) but it's a rather ugly solution.

Can I somehow feed an array of booleans into the DataGrid? I've taken a look various articles on implementing ValueConverters, but I'm not sure that's what I need.


Solution

  • I think you'll have to deal with code behind for this...

    Example:

    Test class:

    public class TestRow
    {
        private bool[] _values = new bool[10];
        public bool[] Values
        {
            get { return _values; }
            set { _values = value; }
        }
    
        public TestRow(int seed)
        {
            Random random = new Random(seed);
            for (int i = 0; i < Values.Length; i++)
            {
                Values[i] = random.Next(0, 2) == 0 ? false : true;
            }
        }
    }
    

    How to generate test data & columns:

    DataGrid grid = new DataGrid();
    var data = new TestRow[] { new TestRow(1), new TestRow(2), new TestRow(3) };
    grid.AutoGenerateColumns = false;
    for (int i = 0; i < data[0].Values.Length; i++)
    {
        var col = new DataGridCheckBoxColumn();
        //Here i bind to the various indices.
        var binding = new Binding("Values[" + i + "]");
        col.Binding = binding;
        grid.Columns.Add(col);
    }
    grid.ItemsSource = data;
    

    What that looks like (lacks headers and everything of course)

    A screenshot of a grid with checkboxes...


    Edit: To make the above code cleaner you should expose a static property in your items-class which is used uniformly when creating the arrays, using data[0].Values.Length when creating the columns could obviously throw an exception if the data collection is empty.