滚动虚拟化WPF Datagrid时,交替行的样式触发器并不总是更新 [英] style triggers for alternating rows don't always update when scrolling virtualized WPF Datagrid

查看:195
本文介绍了滚动虚拟化WPF Datagrid时,交替行的样式触发器并不总是更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里有一些类似的问题,我已经阅读了这个和另一个我找不到链接,但没有一个似乎有一个适用的解决方案。

There are a few questions similar to this on SO, I've read this one and another I can't find the link for, but none of them seem to have a solution that's applicable.

我有一个DataGrid定义如下,并且它具有在AlternationIndex为0或1触发的各种样式。当我向上滚动时,有时给定的单元格将从一种颜色翻转到另一种颜色。

I have a DataGrid defined below, and it has various styles triggered on AlternationIndex being either 0 or 1. When I scroll upwards, sometimes the a given cell will flip from one colour to the other.

你知道有什么办法阻止这种情况发生,而不关闭虚拟化?

Do you know of any way to stop this from happening without turning off virtualization?

采用列定义来节省空间,我不认为它们对于这个很重要,所有的DataTriggers都是这样,这只是我遇到的问题。)

(I've taken the column definitions out to save space, I don't think they're important for this. All of the DataTriggers -always- work, it's just the alternation that I'm having issues with.)

<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

That's the nature of virtualization. Only a set number of UI objects are actually rendered, and when you scroll you are changing the DataContext behind those objects.

所以在你的情况下,创建行并给出一个背景颜色。当您滚动时,这些行后面的 DataContext 会更改,因此数据对象可能位于给定颜色A的某一滚动位置的行中,或者位于在另一个滚动位置被分配了颜色B.

So in your case, Rows are created and given a background color. When you scroll, the DataContext behind those rows change, so a data object might be in a row that was given Color A at a certain scroll position, or be in a row that was assigned color B at another scroll position.

大多数时候,交替颜色只是在那里帮助确定什么列在什么行,所以没有关系它们会更改,但是如果要为行保持一致的背景颜色,则可能需要向数据对象添加一些内容,并将该背景颜色设置为该属性。当您滚动并且 DataContext 更改时,行颜色也将更改。

Most of the time the alternating colors are only there to help identify what columns are in what row so it doesn't matter if they change, however if you want to maintain a consistent background color for the rows you will probably have to add something to the data object and base your background color off that property. That way when you scroll and the DataContext changes, the row color will also change.

这篇关于滚动虚拟化WPF Datagrid时,交替行的样式触发器并不总是更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆