Unable to add binding to UWP DataGridTemplateColumn

0

I want to bind some data to columns created dynamically in my code behind. It's working with DataGridTextColumn but not with DataGridTemplateColumn.

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 he 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)

c#
xaml
uwp
datagrid
asked on Stack Overflow Sep 12, 2020 by Pierre mrq • edited Sep 12, 2020 by Brian Tompsett - 汤莱恩

1 Answer

0

Ok so it's working correctly now and it was an easy fix. The issue was the incorrect usage of Contentproperty, since my StackPanel (in DataTemplate) doesn't have one it's getting this error. The correct property is DataContextProperty.

  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);
       return element;
     }
   }

Thanks to @PeterFleischer-3316 from Microsoft Q&A for solving the issue.

answered on Stack Overflow Sep 14, 2020 by Pierre mrq

User contributions licensed under CC BY-SA 3.0