SO上有几个类似的问题,我读过一个又一个我找不到链接的问题,但它们似乎都没有适用的解决方案。
我在下面定义了一个DataGrid,它在AlternationIndex为0或1时触发了各种样式。当我向上滚动时,有时给定的单元格会从一种颜色切换到另一种颜色。
您知道有什么方法可以在不关闭虚拟化的情况下阻止这种情况的发生吗?
(为了节省空间,我去掉了列定义,我认为它们对此并不重要。所有的DataTriggers总是有效的,这只是我遇到的问题。)
<DataGrid
ItemsSource="{Binding Path=LogItems, Mode=OneWay}"
Grid.Row="1"
AlternationCount="2"
Name="logDataGrid"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<DataGrid.Resources>
<local:IsEntryExceptionConverter x:Key="isEntryExceptionConverter" />
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Name="DataGridCellBorder">
<ContentControl Content="{TemplateBinding Content}">
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Background="Transparent" TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis"
Height="auto" Width="auto" Text="{Binding Text}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="TextBlock.Foreground" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
<SolidColorBrush x:Key="ExceptionBrush" Color="OrangeRed" Opacity="0.5"/>
<SolidColorBrush x:Key="ErrorBrush" Color="Red" Opacity="0.5"/>
<SolidColorBrush x:Key="WarningBrush" Color="Orange" Opacity="0.5"/>
<SolidColorBrush x:Key="AlternatingRowBackground0" Color="AliceBlue" Opacity="0.5" />
<SolidColorBrush x:Key="AlternatingRowBackground1" Color="LightBlue" Opacity="0.5" />
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="{StaticResource AlternatingRowBackground0}" />
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="{StaticResource AlternatingRowBackground1}" />
</Trigger>
<DataTrigger Binding="{Binding Path=Level}" Value="Warning">
<Setter Property="Background" Value="{StaticResource WarningBrush}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Message, Converter={StaticResource isEntryExceptionConverter}}" Value="True">
<Setter Property="Background" Value="{StaticResource ExceptionBrush}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Level}" Value="Error">
<Setter Property="Background" Value="{StaticResource ErrorBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
这就是虚拟化的本质。实际上只渲染了一定数量的UI对象,滚动时会更改这些对象后面的DataContext
。
因此,在您的案例中,Rows被创建并被赋予背景颜色。当您滚动时,这些行后面的DataContext
会发生变化,因此数据对象可能在某个滚动位置被赋予颜色a的行中,或者在另一个滚动位置上被赋予颜色B的行中。
大多数情况下,交替的颜色只是用来帮助识别哪一行中的哪些列,因此它们是否更改并不重要,但是,如果您想为行保持一致的背景色,则可能需要向数据对象添加一些内容,并将背景色基于该属性。这样,当您滚动并且DataContext
发生变化时,行的颜色也会发生变化。