[UWP] Unable to add binding to DataGridTemplateColumn

Pierre MRQ 136 Reputation points
2020-09-12T17:53:26.27+00:00

I want to bind some data to columns created dynamically in my code behind. It's working with DataGridTextColumn but not with DataGridTemplateColumn (Microsoft.Toolkit.Uwp.UI.Controls).

Since DataGridTemplateColumn doesn't have a "Binding" property, I created a custom column deriving from DataGridTemplateColumn as some solutions suggested. However the SetBinding throw a System.Exception when GenerateElement method is called and crashes the program.

class DataGridBoundColumn : DataGridTemplateColumn
{
    public BindingBase Binding { get; set; }

protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
    var element = base.GenerateEditingElement(cell, dataItem);
    if (element != null && Binding != null)
        element.SetBinding(ContentPresenter.ContentProperty, Binding);
    return element;
}

protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
    var element = base.GenerateElement(cell, dataItem);
    if (element != null && Binding != null)
        element.SetBinding(ContentPresenter.ContentProperty, Binding);//Error is here
    return element;
}
}

The code used to create columns and to populate the grid:

dataGrid.Columns.Add(new Models.DataGridBoundColumn
{
    Header = " Week" + week.WeekNumber,
    Binding = new Binding { Path = new PropertyPath("[" + i.ToString() + "]") },
    CellTemplate = (DataTemplate)Resources["templateCell"]
});

var collection = new ObservableCollection<object>();
List<string> list = new List<string>(new string[] { "2", "3", "7" });
for (int i= 0; i < list.Count; i++)//Trying with some test data
{
    collection.Add(list);
}
dataGrid.ItemsSource = collection;

The DataTemplate I'm using for testing at the moment:

<DataTemplate x:Key="templateCell">
    <StackPanel>
        <TextBlock Text="{Binding WeekNumber}" />
        <Rectangle HorizontalAlignment="Left" Height="18" Width="20" Fill="{Binding ItemColor}" />
    </StackPanel>
</DataTemplate>

I have looked closely at the binding class documentation, but I have still no clue why it's throwing this exception...

The error is :

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

at Windows.UI.Xaml.FrameworkElement.SetBinding(DependencyProperty dp, BindingBase binding) at Application.Models.DataGridBoundColumn.GenerateElement(DataGridCell cell, Object dataItem) in C:...\Models\DataGridBoundColumn.cs:line 26 at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.PopulateCellContent(Boolean isCellEdited, DataGridColumn dataGridColumn, DataGridRow dataGridRow, DataGridCell dataGridCell) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.AddNewCellPrivate(DataGridRow row, DataGridColumn column) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.CompleteCellsCollection(DataGridRow dataGridRow) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.GenerateRow(Int32 rowIndex, Int32 slot, Object dataContext) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.AddSlots(Int32 totalSlots) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.RefreshRows(Boolean recycleRows, Boolean clearRows) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.RefreshRowsAndColumns(Boolean clearRows) at Microsoft.Toolkit.Uwp.UI.Controls.DataGrid.MeasureOverride(Size availableSize)

I'm also very interested in if there are other ways of binding an unknown amount of columns.
Thanks in advance!

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,326 Reputation points
    2020-09-13T10:35:26.237+00:00

    Hi Pierre,
    change ContentProperty to DataContextProperty and it works fine:

      class DataGridBoundColumn : DataGridTemplateColumn
      {
        public BindingBase Binding { get; set; }
    
        protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
          var element = base.GenerateEditingElement(cell, dataItem);
          if (element != null && Binding != null)
            element.SetBinding(ContentPresenter.DataContextProperty, Binding);
          return element;
        }
    
        protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
          var element = base.GenerateElement(cell, dataItem);
          if (element != null && Binding != null)
            element.SetBinding(ContentPresenter.DataContextProperty, Binding);//Error is here
          return element;
        }
      }
    

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.