我有一个 WPF 应用程序,它使用一个DataGrid
控件并被警车中的警察使用。我使用合并字典来实现日夜“模式”,当您在两者之间切换程序时,调色板会发生变化。该应用程序从我公司制造的特殊传感器收集数据并将其显示给官员。
有DataGrid
问题的行为很奇怪。程序第一次启动时,它最初是空的。收集数据时,会将行添加到DataGrid
. 当您启动程序时,它最初处于日间模式。问题是第一行的背景没有更改为控件的夜间模式颜色。它保持白色,这是日间模式颜色。如果您在白天模式和夜间模式之间来回切换,它会保持白色。
这与添加到该行DataGrid
之后的任何行不同,后者具有正确的颜色并在颜色之间正确地来回切换。
这是我在 App.xaml 中为DataGridRow
该类定义的样式:
<Application x:Class="MyApplication.App"
. . .>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyApplication;component/DayTime.xaml" />
<ResourceDictionary>
. . .
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="BorderBrush" Value="{DynamicResource DataBorder}" />
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Setter Property="Foreground" Value="{DynamicResource DataForeground}" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorderFocused}" />
<Setter Property="Foreground" Value="{DynamicResource DataForeground}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorderFocused}" />
<Setter Property="Foreground" Value="{DynamicResource DataForeground}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource DataBackgroundSelected}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorderSelected}" />
<Setter Property="Foreground" Value="{DynamicResource DataForegroundSelected}" />
</Trigger>
</Style.Triggers>
</Style>
. . .
</ResourceDictionary>
</ResourceDictionary>
</ResourceDictionary>
</Application.Resources>
</Application>
当我在程序上运行 Snoop 并深入到有DataGridRow
问题的地方时,该Background
属性的值为白色 (#FFFFFFFF),并且它的值源设置为“DefaultStyle”。不过,这似乎不是我定义的风格,因为当我切换到白天模式并返回白色时,它并没有改变。我认为这是微软定义的默认样式,根本没有使用我的样式。但仅在插入的第一行上,DataGrid
如果它最初是空的。
对于后续行,Value Source 列显示为“ParentTemplate”。这一定是我的风格,因为当您切换夜间模式时,背景颜色会正确更改。
我该如何解决这个问题,以使每一行都DataGrid
正确?
编辑:
为了完整起见,这里是DataGrid
控件使用的样式,以防万一。
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Setter Property="Foreground" Value="{DynamicResource TextForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorder}" />
<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 BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<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" />
</Grid.RowDefinitions>
<Button Command="{x:Static DataGrid.SelectAllCommand}"
Focusable="false"
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 Grid.Column="1"
x:Name="PART_ColumnHeadersPresenter"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.ColumnSpan="2"
Grid.Row="1" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="2"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
Grid.Row="1"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}"
MinWidth="45" Width="50" />
<Grid Grid.Column="1"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportWidth}" />
</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>
编辑:
作为经验,我将此成员变量添加到存在问题的窗口的代码隐藏中:
private static Style dataGridRowStyle = null;
然后我将此代码添加到我的窗口的构造函数中:
if ( dataGridRowStyle == null ) {
dataGridRowStyle = FindResource( typeof( DataGridRow ) ) as Style;
MyGrid.RowStyle = dataGridRowStyle;
}
通过这样做,我看到添加到的每一行都DataGrid
具有原始的默认样式。当我将上述代码移至Loaded
事件处理程序时,也发生了这种情况。
接下来,我删除了上面的代码,并Style
在 app.xaml 文件中的定义中添加了一个 x:Key 属性。然后我将此属性添加到DataGrid
控件的定义中:
RowStyle={DynamicResource MyDataGridRowStyle}
现在每一行都有我的风格。这很好,但我认为TargetType
仅使用属性声明我的样式就足以让它应用于所有行。为什么没有呢?