views:

542

answers:

3

I've created a grid of super headers that bind to a datagrid. The super headers stay positioned over their respective datagrid columns during resizing of datagrid columns.

The XAML binding is great and everything works fine.

The only problem however, is that I need to be able to construct this dynamically in C# code. Tried a number of approaches, but I can't get the binding to work.

What is the C# equivlent of the following XAML

Thanks.

<Window x:Class="TESTDataColumnWidthBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="419" Width="827" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"&gt;
<Grid x:Name="windowGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="2*"/>
    </Grid.RowDefinitions>
        <Grid Grid.Row="0" x:Name="SuperHeaderGrid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="{Binding ElementName=DetailDataGrid, Path=RowHeaderWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column0, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column1, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column2, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column3, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column4, Path=ActualWidth}" />
            </Grid.ColumnDefinitions>
            <Border Grid.Column="2" Grid.ColumnSpan="5" BorderBrush="Gray" Background="AliceBlue" HorizontalAlignment="Stretch" BorderThickness="1">
                <Label>Super Header 1</Label>
            </Border>
        </Grid>
        <Grid Grid.Row="1" x:Name="CategoryHeaderGrid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="{Binding ElementName=DetailDataGrid, Path=RowHeaderWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column0, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column1, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column2, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column3, Path=ActualWidth}" />
                <ColumnDefinition Width="{Binding ElementName=Column4, Path=ActualWidth}" />
            </Grid.ColumnDefinitions>
            <Border Grid.Column="2" Grid.ColumnSpan="2" BorderBrush="Gray" Background="Beige" HorizontalAlignment="Stretch" BorderThickness="1">
                <Label>Cat 1</Label>
            </Border>
            <Border Grid.Column="4" Grid.ColumnSpan="2" BorderBrush="Gray" Background="AntiqueWhite" HorizontalAlignment="Stretch" BorderThickness="1">
                <Label>Cat 2</Label>
            </Border>
        </Grid>

    <my:DataGrid Grid.Column="0" Grid.ColumnSpan="15" Grid.Row="3" x:Name="DetailDataGrid" ItemsSource="{Binding Path=.}" AlternatingRowBackground="AliceBlue">
        <my:DataGrid.Columns>
            <my:DataGridTextColumn x:Name="Column0" Header="ID" />
            <my:DataGridTextColumn x:Name="Column1" Header="Count1" />
            <my:DataGridTextColumn x:Name="Column2" Header="Count2" />
            <my:DataGridTextColumn x:Name="Column3" Header="Count3" />
            <my:DataGridTextColumn x:Name="Column4" Header="Count4" />
        </my:DataGrid.Columns>
    </my:DataGrid>
</Grid>

A: 

should be equivalent to:

Binding cdBinding = new Binding("RowHeaderWidth"); cdBinding.Source = DetailDataGrid;

ColumnDefinition colDef = new ColumnDefinition(); colDef.SetBinding(ColumnDefinition.WidthProperty, cdBinding);

SuperHeaderGrid.ColumnDefinitions.Add(colDef);

And similarly for the other column definitions.

Timores
A: 

I need to do the same thing GoAztecs is trying to do in code. For my application, the DetailDataGrid can be set up in XAML, but all of its columns must be dynamically created in code. I have not been able to figure out how to set the x:Name for each column. This is necessary because in creating the Binding for the ColumnDefinition, I have to set the ElementName (Column0...4 in GoAztec's example XAML).

Timores, can you help? Many thanks!

DTayntor
I still don't know how to programmatically set the x:Name for a column, but I think I figured out how to do it without that. Instead of using ElementName for the ActualWidth binding, set the Source to dataGridTextColumn0 (where this is the variable name in code, not the x:Name).
DTayntor
A: 

I don't get binding to width of ColumnDefinition to work.

for (int i = 0; i < nrColumns; i++) { // Create column in the data grid bound to the column data DataGridTextColumn dataGridColumn = new DataGridTextColumn(); dataGridColumn.Binding = new Binding(String.Format("Contents[{0}]", i)); dataGridColumn.IsReadOnly = true; dataGridColumn.Header = String.Format("Header {0}", i + 1); dataGrid.Columns.Add(dataGridColumn);

// Add column to the header span grid, bound to the width of the data grid column ColumnDefinition headerSpanColumn = new ColumnDefinition(); Binding binding = new Binding("ActualWidth"); binding.Source = dataGridColumn; BindingOperations.SetBinding(headerSpanColumn, ColumnDefinition.WidthProperty, binding); ColumnHeaders.ColumnDefinitions.Add(headerSpanColumn); }

Bonny