Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add a footer row in a WPF datagrid?

Tags:

c#

wpf

How Do I Add a footer row in WPF datagrid? I had to add a row in a WPF datagrid for the sum of each column, I don't want to use any dll or telerik and some things like that only use Microsoft components to do this. I'm trying to do it this way:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="Foreground"
    Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" />
                <GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" />
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
    <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
    <Setter Property="ScrollViewer.PanningMode" Value="Both" />
    <Setter Property="Stylus.IsFlicksEnabled" Value="False" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGrid}">
                <Border x:Name="border"
        SnapsToDevicePixels="True"
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}"
        Padding="{TemplateBinding Padding}">
                    <Border.Background>
                        <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                    </Border.Background>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="border"
                                        Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource ControlLightColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Normal" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false" Background="Black">
                        <ScrollViewer.Template>
                            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="Auto" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>

                                    <Button Focusable="false"
                                        Command="{x:Static DataGrid.SelectAllCommand}"
                                        Style="{DynamicResource {ComponentResourceKey 
                                    ResourceId=DataGridSelectAllButtonStyle, 
                                    TypeInTargetAssembly={x:Type DataGrid}}}"
                                        Visibility="{Binding HeadersVisibility, 
                                    ConverterParameter={x:Static DataGridHeadersVisibility.All}, 
                                    Converter={x:Static DataGrid.HeadersVisibilityConverter}, 
                                    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                        Width="{Binding CellsPanelHorizontalOffset, 
                                    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />

                                    <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
                                            Grid.Column="1"
                                            Visibility="{Binding HeadersVisibility, 
                ConverterParameter={x:Static DataGridHeadersVisibility.Column}, 
                Converter={x:Static DataGrid.HeadersVisibilityConverter}, 
                RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />

                                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
                                    Grid.ColumnSpan="2"
                                    Grid.Row="1"
                                    CanContentScroll="{TemplateBinding CanContentScroll}" />

                                    <ScrollBar x:Name="PART_VerticalScrollBar"
                        Grid.Column="2"
                        Grid.Row="1"
                        Orientation="Vertical"
                        ViewportSize="{TemplateBinding ViewportHeight}"
                        Maximum="{TemplateBinding ScrollableHeight}"
                        Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
                        Value="{Binding VerticalOffset, Mode=OneWay, 
                            RelativeSource={RelativeSource TemplatedParent}}"/>
                                    <TextBlock Grid.Row="2" Grid.Column="1" Text="This is footer!"/>
                                    <Grid Grid.Column="1" Grid.Row="3">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, 
                    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                                            <ColumnDefinition Width="*" />
                                        </Grid.ColumnDefinitions>

                                        <ScrollBar x:Name="PART_HorizontalScrollBar"
                        Grid.Column="1"
                        Orientation="Horizontal"
                        ViewportSize="{TemplateBinding ViewportWidth}"
                        Maximum="{TemplateBinding ScrollableWidth}"
                        Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
                        Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                                    </Grid>
                                </Grid>
                            </ControlTemplate>
                        </ScrollViewer.Template>
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsGrouping" Value="true">
            <Setter Property="ScrollViewer.CanContentScroll" Value="false" />
        </Trigger>
    </Style.Triggers>
</Style>

I also tried adding a grid instead of textblock, but when resizing datagrid columns, they can't resize and looks very ugly.

like image 632
HamidEbr Avatar asked Dec 17 '14 09:12

HamidEbr


People also ask

How do I add a footer in WPF?

You can set footer content to SfChart by placing SfChart in the upper row and setting footer in a row beneath in the Grid's RowDefinitions.

Can user add rows DataGrid WPF?

WPF DataGrid (SfDataGrid) provides built-in row called AddNewRow. It allows user to add a new row to underlying collection. You can enable or disable by setting SfDataGrid.

How do you add rows and columns to a WPF grid programmatically?

RowDefinitions. Add(new RowDefinition()); Then just add your user control to the grid, and assign it the row number.

What is the difference between grid and DataGrid in WPF?

A Grid is a control for laying out other controls on the form (or page). A DataGrid is a control for displaying tabular data as read from a database for example.


2 Answers

Answer By Heena Patil has some issues. When the layout of the DataGrid changes, like when the scrollbar is visible or window resized. Then the position of footer changes.

The concept is to set the margin-left and width of the footer TextBlocks when the layout is updated.

<DataGrid x:Name="DGSalesINvoice" LayoutUpdated="DG_LayoutUpdated">
    <DataGridTextColumn x:Name="DG_COL_IdSalesInvoice" Width="Auto" Header="ID" Binding="{Binding IdSalesInvoice}" />
    <DataGridTextColumn x:Name="DG_COL_CustomerName" Width="*" Header="Customer" Binding="{Binding CustomerName}" />
    <DataGridTemplateColumn x:Name="DG_COL_SalesInvoiceAmount" Width="Auto" Header="Invoice Amount">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock HorizontalAlignment="Right" Text="{Binding SalesAmount}"></TextBlock>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTemplateColumn x:Name="DG_COL_EditBtn" Width="50">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Button x:Name="btnEditCompany" Tag="{Binding IdSalesInvoice}">Edit</Button>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid>
<StackPanel Orientation="Horizontal" Grid.Row="2" Background="GhostWhite">
    <TextBlock x:Name="lblTotal" TextAlignment="Right" FontWeight="Bold">Total</TextBlock>
    <TextBlock x:Name="lblTotalSalesInvoiceAmount" TextAlignment="Right" FontWeight="Bold">0.00</TextBlock>
</StackPanel>

private void DGSalesINvoice_LayoutUpdated(object sender, EventArgs e)
{
    Thickness t = lblTotal.Margin;
    t.Left = (DGSalesINvoice.Columns[0].ActualWidth + 7);
    lblTotal.Margin = t;
    lblTotal.Width = DGSalesINvoice.Columns[1].ActualWidth;

    lblTotalSalesInvoiceAmount.Width = DGSalesINvoice.Columns[2].ActualWidth;
}

Result

like image 107
Mohamed Navas Avatar answered Sep 19 '22 17:09

Mohamed Navas


Try this.

<ScrollViewer  VerticalAlignment="Top" HorizontalScrollBarVisibility="Auto">
    <StackPanel>
        <DataGrid ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Header1" Header="Header1"></DataGridTextColumn>
                <DataGridTextColumn x:Name="Header2" Header="Header2"></DataGridTextColumn>
                <DataGridTextColumn x:Name="Header3" Header="Header3"></DataGridTextColumn>
            </DataGrid.Columns>
            <TextBlock></TextBlock>
            <TextBlock></TextBlock>                          
        </DataGrid>
        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
            <Grid Width="{Binding ElementName=Header1,Path=ActualWidth}">
                <TextBlock Margin="5,0,0,0" Text="Footer1"></TextBlock>
            </Grid>
            <Grid Width="{Binding ElementName=Header2,Path=ActualWidth}">
                <TextBlock Text="Footer2" Margin="5,0,0,0"></TextBlock>
            </Grid>
            <Grid Width="{Binding ElementName=Header3,Path=ActualWidth}">
                <TextBlock Text="Footer3" Margin="5,0,0,0"></TextBlock>
            </Grid>
        </StackPanel>
    </StackPanel>
</ScrollViewer>

Result enter image description here

like image 39
Heena Avatar answered Sep 19 '22 17:09

Heena