Search code examples
c#wpf.net-3.5wpfdatagrid

Showing message 'No data' when WPF DataGrid has no rows


I have a WPF DataGrid in which I want to show a message 'No data' when there are no records within it. So I have done what is explained here in the answer provided by pchajer but when datagrid is show with no data the message is not show. I think I am having problems with AncestorType, I think I am not specifying correctly, but I do not know how to solve this. I do not understand at all how AncestorType works...

Below my code:

<Window x:Class="My.Apps.WPF.Test.wMain"
        xmlns:local="clr-namespace:My.Apps.WPF.Test">

<dg:DataGrid.Style>
    <Style TargetType="dg:DataGrid">
        <Setter Property="RowDetailsVisibilityMode" Value="Collapsed"></Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding DataContext.IsRecordExists, 
                                   RelativeSource={RelativeSource Mode=FindAncestor,
                                                                  AncestorType={x:Type local:wMain}}}" Value="false">
                <Setter Property="RowHeight" Value="0"></Setter>
                <Setter Property="RowDetailsVisibilityMode" Value="Visible"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</dg:DataGrid.Style>

<!-- Missatge quan no hi ha documents pel procés seleccionat -->
<dg:DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <StackPanel>
            <TextBlock Text="No hi ha documents disponibles pel procés seleccionat" Width="400"></TextBlock>
        </StackPanel>
    </DataTemplate>
</dg:DataGrid.RowDetailsTemplate>

</Window>

Code-behind (XAML.cs):

namespace My.Apps.WPF.Test
{
    public partial class wMain : ViewBaseControl
    {

    }
}

Solution

  • You could bind to the DataGrid's HasItems property and change the template:

    <DataGrid.Style>
        <Style TargetType="DataGrid">
            <Style.Triggers>
                <DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="false">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="DataGrid">
                                <TextBlock Text="No data..." />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Style>
    

    There will never be any row details to display if there are no rows in the DataGrid so that approach won't work.

    Edit: If you want to display the column headers even when there are no rows, you should include a DataGridColumnHeadersPresenter in the template:

    <DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="false">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGrid">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <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}}}"/>
                        <TextBlock Text="No data..." Grid.Row="1" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </DataTrigger>