Apply CellTemplate to DataGrid bound to dynamic DataTable

686 Views Asked by At

My application builds a datatable (rows & column) at runtime, so the columns/properties are variable. Now I'm displaying it in a datagrid & trying to set CellTemplate and unsuccessfully binding each cell value. It shows values correctly before applying the CellTemplates...

Here's the code I'm building the datagrid with & designating cell styles:

 private void BuildDataGridColumnsFromDataTable(DataTable dT)
    {
        foreach (DataColumn dTColumn in dT.Columns) 
        {
            var binding = new System.Windows.Data.Binding(dTColumn.ToString());

            DataTemplate dt = null;
            if (dTColumn.ColumnName == "Country")
            {
                GridTextColumn textColumn = new GridTextColumn();
                textColumn.MappingName = "Country";
                textColumn.Width = 100;

                MatrixDataGrid.Columns.Add(textColumn);
            }
            else
            {
                dt = (DataTemplate)Resources["NameTemplate"];
                GridTextColumn textColumn = new GridTextColumn();
                textColumn.MappingName = dTColumn.ColumnName;
                textColumn.CellTemplate = dt;

                MatrixDataGrid.Columns.Add(textColumn);
            }
        }
    }

And a cell style. I've been unable to retreive each datatable cell value. So for instance here I'd just take the original datatable cell values & bind/display them in each datagrid textblock.

    <DataTemplate x:Key="NameTemplate">
        <TextBlock Name="NameTextBlock" DataContext="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Converter={StaticResource drvc}}" 
                   Text="{Binding}" Background="LightGreen"/>
    </DataTemplate>

----EDIT---

I'm able to achieve it by building a datatemplate in code-behind & passing the runtime created column(property) like this:

textColumn.CellTemplate = GetDataTemplate(dTColumn.ColumnName);

I'd much prefer building this in XAML though... so what I'm really needing is to pass the column parameter to XAML. Any ideas how to best achieve this would be very much appreciated!

        private static DataTemplate GetDataTemplate(string col) 
    {
        DataTemplate template = new DataTemplate();
        FrameworkElementFactory txtBox = new FrameworkElementFactory(typeof(TextBox));
        txtBox.SetValue(TextBox.TextAlignmentProperty, TextAlignment.Center);
        txtBox.SetValue(TextBox.BackgroundProperty, (Brush)(new BrushConverter()).ConvertFromString("#9EB11C"));
        template.VisualTree = txtBox;

        System.Windows.Data.Binding bind = new System.Windows.Data.Binding
        {
            Path = new PropertyPath(col), //Provides the column (property) at runtime.
            Mode = BindingMode.TwoWay
        };

        // Third: set the binding in the text box
        txtBox.SetBinding(TextBox.TextProperty, bind);

        return template;
    }
2

There are 2 best solutions below

0
On BEST ANSWER

so what I'm really needing is to pass the column parameter to XAML

I am afraid there is no "XAML solution" to bind to a property whose name is not known at build time. After all XAML is a markup language.

So you will have to create a DataTemplate per column programmatically and dynamically like you are currently doing in your GetDataTemplate method. You cannot do something like Text="{Binding [DynamicValue]}" in XAML.

1
On

You can refer this forum to bind underlying data object dynamically to the property of the control during the DataTemplate creation in code behind.

Note: I work for Syncfusion.