Search code examples
c#.netwpfwpfdatagrid

How to convert below xaml Programmatically?


I want format Header like in image (INWARD in First Line, Gross Wt., Pure Wt. & Qty. in Second Line). I can achieve same with following code in XAML, but how can I do this Programmatically?

XAML:

   <dg:DataGrid>
        <dg:DataGridTemplateColumn Width="210">
            <dg:DataGridTemplateColumn.HeaderTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <TextBlock Grid.Row="0" 
                                   Text="INWARD" 
                                   TextAlignment="Center">
                        </TextBlock>
                        <StackPanel Grid.Row="1" Orientation="Horizontal">
                            <TextBlock Width="80"
                                       Text="Gross Weight"
                                       TextAlignment="Right"
                                       Margin="0,0,2,0">
                            </TextBlock>
                            <TextBlock Width="80"
                                       Text="Pure Weight" 
                                       TextAlignment="Right"
                                       Margin="0,0,0,0">
                            </TextBlock>
                            <TextBlock Width="40"
                                       Text="Quantity"
                                       TextAlignment="Right"
                                       Margin="2,0,0,0">
                            </TextBlock>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </dg:DataGridTemplateColumn.HeaderTemplate>
            <dg:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <TextBlock Style="{DynamicResource grdCellCurrencyData}" 
                                                       Width="80"
                                                       Margin="0,0,2,0">
                            <TextBlock.Text> 
                                <MultiBinding Converter="{StaticResource CurrencyConverter}" ConverterParameter="True">
                                    <Binding Path="INGrossWeight" Mode="OneWay" />
                                    <Binding Path="BaseUOMNoofDecimals" Mode="OneWay" />
                                </MultiBinding> 
                            </TextBlock.Text>
                        </TextBlock>
                        <TextBlock Style="{DynamicResource grdCellCurrencyData}"
                                                           Width="80"
                                                           Margin="0,0,0 0">
                            <TextBlock.Text> 
                                <MultiBinding Converter="{StaticResource CurrencyConverter}" ConverterParameter="True">
                                    <Binding Path="INPureWeight" Mode="OneWay" />
                                    <Binding Path="BaseUOMNoofDecimals" Mode="OneWay" />
                                </MultiBinding> 
                            </TextBlock.Text>
                        </TextBlock>
                        <TextBlock Style="{DynamicResource grdCellCurrencyData}"
                                   Width="40"
                                   Text="{Binding Path=INQuantity, Mode=OneWay}" Margin="2,0,0,0">
                        </TextBlock>
                    </StackPanel>
                </DataTemplate>
            </dg:DataGridTemplateColumn.CellTemplate>
        </dg:DataGridTemplateColumn>
    </dg:DataGrid>

In above code if you see in DataGridTemplateColumn, I have taken grid inside and split header in two rows. Same way I want to do programmatically from code behind. can anybody help?


Solution

  • You can try and use FrameworkElementFactory to create the DataTemplate for your header programatically, following SO thread is having code related to that - How do I build a DataTemplate in c# code?

    But, as FrameworkElementFactory is deprecated, it would be better to define header template in Resources and use FindResource() to set HeaderTemplate.

    Edit:

    here is your code:

    DataGridTemplateColumn col1 = new DataGridTemplateColumn();
    
    //create the data template 
    DataTemplate headerLayout = new DataTemplate();
    
    //set up the stack panel 
    FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid));
    
    // define grid's rows  
    var row1 = new FrameworkElementFactory(typeof(RowDefinition));
    gridFactory.AppendChild(row1);
    var row2 = new FrameworkElementFactory(typeof(RowDefinition));
    gridFactory.AppendChild(row2);
    
    // set up the inwardTextBlock 
    FrameworkElementFactory inwardTextBlock = new FrameworkElementFactory(typeof(TextBlock));
    inwardTextBlock.SetValue(Grid.RowProperty, 0);
    inwardTextBlock.SetValue(TextBlock.TextProperty, "INWARD");
    gridFactory.AppendChild(inwardTextBlock);
    
    //set up the stack panel 
    FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
    spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
    spFactory.SetValue(Grid.RowProperty, 1);
    
    // set up the grossWeightTextBlock 
    FrameworkElementFactory grossWeightTextBlock = new FrameworkElementFactory(typeof(TextBlock));
    inwardTextBlock.SetValue(TextBlock.TextProperty, "Gross Weight");
    inwardTextBlock.SetValue(TextBlock.WidthProperty, 80);
    spFactory.AppendChild(inwardTextBlock);
    
    // set up the pureWeightTextBlock 
    FrameworkElementFactory pureWeightTextBlock = new FrameworkElementFactory(typeof(TextBlock));
    inwardTextBlock.SetValue(TextBlock.TextProperty, "Pure Weight");
    inwardTextBlock.SetValue(TextBlock.WidthProperty, 80);
    spFactory.AppendChild(inwardTextBlock);
    
    // set up the qtyWeightTextBlock 
    FrameworkElementFactory qtyWeightTextBlock = new FrameworkElementFactory(typeof(TextBlock));
    inwardTextBlock.SetValue(TextBlock.TextProperty, "Quantity");
    inwardTextBlock.SetValue(TextBlock.WidthProperty, 80);
    spFactory.AppendChild(inwardTextBlock);
    
    gridFactory.AppendChild(spFactory);
    
    // set the visual tree of the data template 
    headerLayout.VisualTree = gridFactory;
    
    // set the header template
    col1.HeaderTemplate = headerLayout;