带有MVVM的WPF DataGrid行样式
本文关键字:样式 DataGrid WPF MVVM 带有 | 更新日期: 2023-09-27 18:21:29
我有一个DataGrid,如果ViewModel类的某个属性设置为true,我想在其中更改行边界颜色或背景。我在将DataTrigger绑定到行源项(ViewModel)属性时遇到问题。在这种情况下,我希望绑定到ViewModel属性IsExpired。不幸的是,它不允许我在运行时抛出和异常。如有任何帮助,我们将不胜感激。
public class ViewModel
{
public uint Id { get; private set;}
public string Symbol { get; private set;}
public bool IsExpired { get; private set;}
}
public class WindowViewModel : PropertyChangedNotifier
{
public ObservableCollection<ViewModel> ViewModels { get; private set;}
private DateTime _timestamp;
public DateTime TimeStamp
{
get { return _timestamp; }
set
{
_timestamp = value;
OnPropertyChanged("TimeStamp");
}
}
}
<Grid x:Name="Layout" d:DataContext="{StaticResource DesignerViewModel}" DataContext="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="Accounts" VerticalAlignment="Center" Margin="5"/>
<ComboBox x:Name="AccountsComboBox" ItemsSource="{Binding Accounts}" DisplayMemberPath="ClearingNumber" Width="125"
HorizontalAlignment="Left" Margin="5" IsEditable="False" IsReadOnly="True" Style="{StaticResource AccountComboBoxStyle}"/>
<Button x:Name="LoadPositionsButton" Content="Load" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Click="LoadPositionsButtonOnClick"/>
<TextBlock x:Name="TimeStampTextBlock" HorizontalAlignment="Right" Margin="5" Width="150" Text="{Binding LastUpdate, Converter={StaticResource TimeStampConverter}}"/>
</StackPanel>
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!-- ... -->
<DataGrid.Columns>
<DataGridTemplateColumn Header="Account">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Account}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--<DataGridTemplateColumn Header="Exch">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding ExchangeCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>-->
<DataGridTemplateColumn Header="Symbol">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Symbol}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Description">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Maturity">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding MaturityMonthYear}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGrid.Columns>
</DataGrid>
</Grid>
首先应该为ViewModel
类实现INotifyPropertyChanged
接口。这与你在WindowViewModel
课上的写作方式类似。然后将自动属性IsExpired
更改为:
public bool IsExpired
{
get { return _isExpired; }
set
{
_isExpired = value;
OnPropertyChanged("IsExpired");
}
}
其次,如果您想更改某个列的样式,您应该更改列的CellStyle
属性:
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTemplateColumn Header="HeaderName" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Symbol}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
</DataGrid.Columns>
<!-- ... -->
</DataGrid>
如果您想更改数据网格行的样式,您应该使用Template
属性,例如:
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DataGridRowBorder"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<!-- Row template -->
<Grid>
<TextBlock Text="{Binding Path=Symbol}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter TargetName="DataGridRowBorder" Property="BorderBrush" Value="Red"/>
<Setter TargetName="DataGridRowBorder" Property="BorderThickness" Value="1"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
<!-- ... -->
</DataGrid>