katit
katit

Reputation: 17895

Programmatically bind DataGridTemplateColumn

Here is my code:

foreach (var columnData in lookup.DataProvider.Metadata)
    {
        DataGridColumn column = new DataGridTextColumn { Binding = new Binding(columnData.FieldName) };

        if (columnData.DataType == typeof(bool))
        {
            column = new DataGridCheckBoxColumn { Binding = new Binding(columnData.FieldName) };
        }

        if (columnData.DataType == typeof(DateTime))
        {
            column = new DataGridTemplateColumn();
            //... ????
        }

        column.Header = columnData.Caption;

        DataDataGrid.Columns.Add(column);
    }

Basically, I'm creating columns and bindings in code because columns not known at design-time.

Now I need to add templated column and not sure how to write it in C#. Here is example of XAML of column I need to add:

<sdk:DataGridTemplateColumn Header="Received" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" SortMemberPath="SomeTime">
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <MyControls:MyDateTimeLabel DisplayUtcDate="{Binding SomeTime}" />
        </DataTemplate>
    </sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>

EDIT

In case someone interested. I used solution from here: http://www.pettijohn.com/2011/01/silverlight-datagrid-with-dynamic.html

I took version with XAML loader. It definitely smells since I got my namespaces etc hardcoded into strings.

So, I started to explore second choice. Here is how my dynamic column looks now:

column = new DataGridTemplateColumn
            {
                CanUserSort = true,
                SortMemberPath = columnData.FieldName,
                CellTemplate = (DataTemplate)this.Resources["DateTimeColumnDataTemplate"]
            };

I'm loading DateTemplate from resources. This was cool, but how do I do binding? Suggestion here was to get to my DateTimeLabel and set binding. But that didn't work(see article on why). So, I wrote this code and all is well:

private void OnLoadingRow(object sender, DataGridRowEventArgs e)
    {
        foreach (DataGridColumn t in this.DataDataGrid.Columns)
        {
            if (t is DataGridTemplateColumn)
            {
                var label = t.GetCellContent(e.Row) as DitatDateTimeLabel;
                label.SetBinding(DitatDateTimeLabel.DisplayUtcDateProperty, new Binding(t.SortMemberPath));
            }
        }
    }

Upvotes: 3

Views: 5410

Answers (1)

dmusial
dmusial

Reputation: 1564

You could put your DataTemplate inside Page/UserControl resources, retrieve it in code and apply to your column's CellTemplate. It would look sth like this:

column.CellTemplate = (DataTemplate)this.Resources["DateTimeFieldTemplate"];

The binding should work as it is in your DataTemplate XAML right now because on the DataGrid row level your DataContext will be set to the item itself.

Upvotes: 2

Related Questions