我仍然在掌握 WPF 的窍门时遇到一些问题。我觉得这可能是一个简单的问题,我想知道为什么我不能让它像我认为的那样工作。
我正在尝试使用 DataTrigger 来显示我的 DataGrid 中的值是“脏的”,这意味着自上次将数据提交到数据库以来,它的值已经发生了变化。绑定到我的网格视图的项目有一个运行良好的 IsDirty 属性。我正在尝试在网格中单元格的 TextBlock 中使用红色星号来指示存在未提交的更改,使用 DataTrigger,就像这样,在我的 DataGrid.Resources 中。这个想法是,如果所选行项上的 IsDirty 为 True,则字体颜色将从透明变为红色:
<DataTemplate x:Key="CleanTemplate">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Transparent" FontWeight="Bold" FontFamily="Lucida Console" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<!-- Not sure why this isn't working... this text block can't see changes in IsDirty for some reason-->
<DataTrigger Binding="{Binding Path=IsDirty}" Value="True">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
我的猜测是,样式触发器的 DataContext 与实际 TextBlock 的 DataContext 不同(以及 DataGrid 中单元格的一部分),我需要更改绑定路径,以便触发器可以“看到" 所选项目及其属性。我不确定如何导航到可以在网格中看到所选项目属性的位置。
我能够通过 DataGridTemplateColumn 上的 CellTemplateSelector 让它工作,但是客户根据所选行的数据类型请求不同的输入控件,所以现在我的数据模板选择的标准变得更加复杂(现在我需要为每个单独的控件和一个基本相同的模板设置一个模板,除了显示值 IsDirty)。
XAML:
<DataGridTemplateColumn
Header="Value"
Width="*"
MinWidth="25"
>
<DataGridTemplateColumn.CellTemplateSelector>
<local:ParameterStateTemplateSelector
CleanTemplate="{StaticResource CleanTemplate}"
CleanTemplateYN="{StaticResource CleanTemplateYN}"
DirtyTemplate="{StaticResource DirtyTemplate}"
DirtyTemplateYN="{StaticResource DirtyTemplateYN}"
/>
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
Label 类型数据的模板(区别在于 TextBlock 的 Foreground 是透明的还是红色的,取决于 IsDirty):
<DataTemplate x:Key="CleanTemplate">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Transparent" FontWeight="Bold" FontFamily="Lucida Console" />
<Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="DirtyTemplate">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Red" FontWeight="Bold" FontFamily="Lucida Console"/>
<Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
DataTemplateSelector 背后的代码(似乎 IsDirty 的 DataTrigger 会更简单):
public class ParameterStateTemplateSelector : DataTemplateSelector
{
public DataTemplate CleanTemplate { get; set; }
public DataTemplate CleanTemplateYN { get; set; }
public DataTemplate DirtyTemplate { get; set; }
public DataTemplate DirtyTemplateYN { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ScenarioParam selectedItem = (ScenarioParam)item;
if (selectedItem != null)
{
if (selectedItem.ParamObject.DataType == "BOOL")
{
if (selectedItem.IsDirty)
{
return DirtyTemplateYN;
}
else
{
return CleanTemplateYN;
}
}
else
{
if (selectedItem.IsDirty)
{
return DirtyTemplate;
}
else
{
return CleanTemplate;
}
}
}
return base.SelectTemplate(item, container);
}
}
关于如何让 DataTrigger “查看”所选项目属性的更改的任何建议?或者也许不可能以我想要的方式使用 DataTriggers?
谢谢!