Редактировать в соответствии с предположением в комментариях:
Если, как упомянул @bathineni, вы хотите отобразить прямоугольник над DataGrid
, когда в коллекции нет элементов, вы, вероятно, вероятно,Мне нужно использовать механизм, отличный от RowDetailsTemplate
, чтобы добиться этого.
Два примера, о которых я могу подумать, - это стилизация DataGrid, чтобы он содержал выделенный TextBlock для отображения этого сообщения, а другой -создать сетку, которая содержала бы DataGrid и сообщение, которое вы хотели бы отобразить сверху.
Пример первый: Стиль DataGrid
Вы можетенайдите очень хороший учебник здесь , который покажет вам, как стилизовать внутренности DataGrid, аналогично тому, как это делает Самуэль, всего их четыре.
В шаблоне DataGrid окружите всев объекте Grid и создайте сообщение, которое будет отображаться в.
Например: (прошу прощения из длинного кода)
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
Grid.Row="1"
Padding="{TemplateBinding Padding}">
<ScrollViewer Focusable="false" Name="DG_ScrollViewer">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!--Left Column Header Corner -->
<Button
Style="{StaticResource selectAllButtonTemplate}"
Command="{x:Static DataGrid.SelectAllCommand}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}"
Focusable="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" />
<!--Column Headers-->
<Primitives:DataGridColumnHeadersPresenter
Grid.Column="1"
Name="PART_ColumnHeadersPresenter"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/>
<!--DataGrid content-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />
<Border Name="noItemsBorder" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden" SnapsToDevicePixels="True" Background="Coral" BorderBrush="DarkRed" BorderThickness="1" Grid.Row="1" Grid.ColumnSpan="2">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="No items to display" Margin="20" />
</Border>
<ScrollBar
Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Name="PART_VerticalScrollBar"
Orientation="Vertical"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar
Grid.Column="1"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasItems, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="False">
<Setter TargetName="noItemsBorder" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}">Transparent</SolidColorBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">Transparent</SolidColorBrush>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}">Black</SolidColorBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</Style.Triggers>
</Style>
В приведенном вышеНапример, вы можете видеть объект noItemsBorder
, он просто перекрывает объект ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
, когда DataGrid.HasItems
имеет значение false (отображается с помощью триггера), другим способом будет использование привязки к свойству Visibility, но радиЯ использовал триггер в соответствии с вашим вопросом.
Пример два: Одноразовое наложение TextBlock
Это будет похоже на приведенный выше пример, но вместо изменения стиля DataGrid вы просто инкапсулируете два элемента управлениявнутри сетки.
Хотя это будет работать, этот код нужно будет копировать и вставлять везде, где вы хотите его использовать, что не идеально.
Код, как показано ниже:
<Grid>
<DataGrid Name="dg" ItemsSource="{Binding Path=DisplayItems}" />
<Border HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding ElementName=dg, Path=HasItems, Converter={StaticResource booleanToVisibilityConverter}}" SnapsToDevicePixels="True" Background="Coral" BorderBrush="DarkRed" BorderThickness="1">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="No items to display" Margin="20" />
</Border>
</Grid>
Исходное сообщение:
Я не уверен, что вы используете для своих HasItems, но убедитесь, что это свойство, которое вызывает соответствующее событие PropertyChanged.
Этот код работает для меня как ожидалось:
DataGrid XAML
<DataGrid Name="dataGrid" RowDetailsVisibilityMode="VisibleWhenSelected">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=TextToDisplay}" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Name="txtnoitems" Text="No Records Found" Visibility="Collapsed"></TextBlock>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding HasItems}" Value="False">
<Setter TargetName="txtnoitems" Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
(примечание: я также удалил {RelativeSource} вактивировать привязку и установить для свойства RowDetailsVisibilityMode
значение DataGrid)
Некоторые элементы класса (используется в качестве дочерних элементов)
public class SomeItem : INotifyPropertyChanged
{
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
#region HasItems Definition
private bool _HasItems = true;
public bool HasItems
{
get
{
return _HasItems;
}
set
{
_HasItems = value;
OnPropertyChanged("HasItems");
}
}
#endregion // end of HasItems region
#region TextToDisplay Definition
private string _TextToDisplay = null;
public string TextToDisplay
{
get
{
return _TextToDisplay;
}
set
{
_TextToDisplay = value;
OnPropertyChanged("TextToDisplay");
}
}
#endregion // end of TextToDisplay region
public SomeItem(string blah)
{
TextToDisplay = blah;
}
}
Использование:
dataGrid.Items.Add(new SomeItem("items"));
dataGrid.Items.Add(new SomeItem("items"));
dataGrid.Items.Add(new SomeItem("not items") { HasItems = false });
dataGrid.Items.Add(new SomeItem("items"));