Exporting a datagrid with custom column headers

Posted by: firelex on 25 January 2021, 4:09 am EST

    • Post Options:
    • Link

    Posted 25 January 2021, 4:09 am EST

    Hello all,

    I have a datagrid with custom column headers:

    
    <DataTemplate x:Key="gridHeader">
      <StackPanel>
        <TextBlock ... />
        <Separator  ... />
        <TextBlock ... />
        <TextBlock ... />
      </StackPanel>
    </DataTemplate>
    
    

    and in code behind:

    
    DataTemplate dt = FindRessource("gridHeader") as DataTemplate;
    StackPanel sp = dt.LoadContent() as StackPanel;
    TextBlock tb  = sp.Children[0] as TextBlock;
    tb.Text = ...
    
    

    Setting values for all TextBlocks works well.

    Now I want to export the content of the grid as a “*.xlsx”-File.

    The question is: how can I export my complex column headers properly - as text? At the moment cells remain empty in the exported file.

  • Posted 27 January 2021, 6:29 pm EST

    Hi Lex,

    You can override the DataGridColumn’s GetColumnText method and then return the content of the column header template as follows:

    public class DataGridTextColumnEx : C1.WPF.DataGrid.DataGridTextColumn
    {
            public override string GetColumnText()
            {
                try
                {
                    var panel = Header as StackPanel;
                    return $"{(panel.Children[0] as TextBlock).Text} | {(panel.Children[2] as TextBlock).Text}";
                }
                catch
                {
                    return base.GetColumnText();
                }
            }
    }
    

    Best Regards,

    Kartik

  • Posted 29 January 2021, 2:04 am EST

    Thanks, Kartik! That’s exactly what I needed!

    Two more little things:

    1. The first row in the exported file is very high. Surely because of the high header row in the grid. Is there any possibility to fix that?

    2. I use column grouping and now it gets the proper column descriptions (thanks for that also!!). But the grouping bar is also very high. Surely because of the high header row in the grid. Is there any possibility to keep grouping bar old sized?

  • Posted 31 January 2021, 5:37 pm EST

    Hi Lex,

    1. There is no direct way of controlling the height of the header row in Excel. Therefore as a workaround you can change the C1DataGrid’s ColumnHeaderHeight property while exporting as follows:
    
    double currentHeight = dataGrid.ColumnHeaderHeight;
    dataGrid.ColumnHeaderHeight = 20; // set the required height
    
    // save to excel here
    
    dataGrid.ColumnHeaderHeight = currentHeight; // reset the height after exporting
    
    
    1. Did you mean you want to fix the height of the Grouping panel? By default the height of the Grouping panel increases on adding columns. However, you can prevent this by setting the DataGridGroupingPanel’s IndentHeight to ‘0’ as follows:
    
    <c1:DataGrid.GroupingPanelStyle>
           <Style x:Key="DataGridGroupingPresenterStyle" TargetType="{x:Type c1:DataGridGroupingPresenter}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type c1:DataGridGroupingPresenter}">
                            <Grid x:Name="GroupingContent" Grid.ColumnSpan="2">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="GroupsStates">
                                        <VisualState x:Name="Grouped">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Grouping">
                                                    <DiscreteObjectKeyFrame KeyTime="0">
                                                        <DiscreteObjectKeyFrame.Value>
                                                            <Visibility>Visible</Visibility>
                                                        </DiscreteObjectKeyFrame.Value>
                                                    </DiscreteObjectKeyFrame>
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Empty">
                                                    <DiscreteObjectKeyFrame KeyTime="0">
                                                        <DiscreteObjectKeyFrame.Value>
                                                            <Visibility>Collapsed</Visibility>
                                                        </DiscreteObjectKeyFrame.Value>
                                                    </DiscreteObjectKeyFrame>
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Ungrouped">
                                            <Storyboard/>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <c1:C1BrushBuilder x:Name="BackgroundBrush" DesignColor="#FFD1DCE8" ExtrapolationMethod="Absolute" Input="{TemplateBinding Background}">
                                    <c1:C1BrushBuilder.DesignBrush>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FFD1DCE8"/>
                                        </LinearGradientBrush>
                                    </c1:C1BrushBuilder.DesignBrush>
                                </c1:C1BrushBuilder>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,1" Background="{Binding Output, ElementName=BackgroundBrush}" CornerRadius="0"/>
                                <Grid Margin="8">
                                  
                                     [b]<!--Indent height set here-->[/b]
                                    <c1:DataGridGroupingPanel x:Name="Grouping" [b]IndentHeight="0"[/b] Visibility="Collapsed"/>
                                    <TextBlock x:Name="Empty" Opacity="0.7" Text="{Binding EmptyGroupPanel}" TextTrimming="WordEllipsis"><Run Text="Drag a column here to group by that column"/></TextBlock>
    
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    </c1:DataGrid.GroupingPanelStyle>
    
    

    Regards,

    Kartik

  • Posted 3 February 2021, 8:48 pm EST - Updated 3 October 2022, 11:43 pm EST

    Thanks, Kartik!

    The first tip worked perfect for me.

    The second one is not exactly what I meant. Have a look at the pic. Because of the high column header grouping panel gets also high. And when GetColumnText returns single-line column descriptions, an extra space arises in the grouping panel. I marked it with red arrows.

    Is there any possibility to reduce that huge extra space to normal one with 3-4 pixels?

  • Posted 3 February 2021, 10:53 pm EST

  • Posted 3 February 2021, 11:00 pm EST

    Hi Lex,

    Thank you for sharing the snapshot.

    This is the default behavior of DataGridGroupingPanel. Therefore, you need to manually place the grouping panel’s children by overriding the DataGridGroupingPanel’s MeasureOverride and ArrangeOverride method.

    And then you can use the extended DataGridGroupingPanel inside DataGrid’s GroupingPanelStyle.

    Please refer to the attached sample for implementation. (see DataGridGrouping.zip)

    Best Regards,

    Kartik

  • Posted 4 February 2021, 7:31 pm EST

    Thank you, Kartik!

    Your solution worked fine.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels