Столбцы набора инструментов WPF Datagrid не отображаются правильно после прокрутки вниз / вверх - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть приложение WPF MVVM.В основном окне WPF у меня есть набор инструментов WPF Datagrid.Эта сетка данных имеет несколько столбцов.В зависимости от некоторых условий (свойств, связанных с моделью представления) цвет применяется ко всей строке.Дополнительно есть две специальные колонки.Эти два столбца имеют тип DataGridTextColumn и называются Date1 и Date2.Если значение Date1 больше значения Date2, ячейки Date1 и Date2 должны быть окрашены в оранжевый красный цвет.Date1 и Date2, которые связаны со свойствами модели представления MyDate1 и MyDate2 соответственно, имеют тип DateTime.

Моя проблема: во-первых, когда сетка данных загружается с данными, строки и столбцы Date1 и Date2 окрашиваются правильно.Некоторые строки отображаются с Date1 и Date2, окрашенными в оранжевый-красный цвет, поскольку Date1> Date2.Затем, если я прокручиваю вниз, используя вертикальную полосу прокрутки сетки данных, а затем снова прокручиваю вверх до первой строки сетки данных, я отмечаю, что теперь другие строки (столбцы Date1 и Date2) отображаются неправильно окрашенными в оранжевый оранжевый цвет, несмотря на Date1 <= Date2. </p>

Что происходит?

Просмотр :

<Window x:Name="MainWindow" x:Class="My.Apps.WPF.TestApp.wMain"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" 
    xmlns:classes="clr-namespace:My.Apps.WPF.TestApp.Classes"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"        
    WindowState="Maximized">


    <Grid x:Name="MyGrid" HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>

        <my:DataGrid  Grid.Row="1" Name="MyDg"                         
                  AutoGenerateColumns="False"
                  ItemsSource="{Binding Path=MyListOfItems}" 
                  SelectedItem="{Binding Path=MySelectedItem}" 
                  VerticalAlignment="Stretch" IsReadOnly="True" 
                  SelectionMode="Single" ColumnWidth="*"                                   
                  SelectionChanged="MyDg_SelectionChanged"
                  Width="{Binding Path=ActualWidth, ElementName=MyGrid}">

                <my:DataGrid.Resources>
                    <classes:BindingProxy x:Key="proxy" Data="{Binding}" />
                    <Style x:Key="MyDataGridCellStyle" TargetType="{x:Type my:DataGridCell}" BasedOn="{StaticResource {x:Type my:DataGridCell}}">
                        <!-- If Date1 > Date2 apply background color -->
                        <Setter Property="Background">
                            <Setter.Value>
                                <MultiBinding Converter="{StaticResource CellDateColorConverter}">
                                    <Binding Path="MyDate1"/> <!-- Date1 value -->
                                    <Binding Path="MyDate2"/> <!-- Date2 value -->
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </my:DataGrid.Resources>

                <my:DataGrid.RowStyle>
                    <!-- Style for entire datagrid row -->
                    <Style TargetType="my:DataGridRow">
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Path=GroupID, Converter={StaticResource IdGroupConverter}}" Value="True" />
                                    <Condition Binding="{Binding Path=MyFlag}" Value="0" />
                                    <Condition Binding="{Binding Path=StatusFilter, Converter={StaticResource StatusFilterConverter}}" Value="True"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="#FFAC62"></Setter>
                            </MultiDataTrigger>

                            <DataTrigger Binding="{Binding Path=MyFlag}}" Value="1">
                                <Setter Property="Background" Value="{Binding DeniedColor}"></Setter>
                            </DataTrigger>

                            <DataTrigger Binding="{Binding Path=MyFlag}" Value="2">
                                <Setter Property="Background" Value="{Binding PendingColor}"></Setter>
                            </DataTrigger>

                        </Style.Triggers>
                    </Style>
                </my:DataGrid.RowStyle>

                 <my:DataGrid.Columns>

                        <my:DataGridTextColumn x:Name="Date1" 
                                               CellStyle="{StaticResource MyDataGridCellStyle}"
                                               Binding="{Binding Path=MyDate1, StringFormat=\{0:dd/MM/yyyy\}}" 
                                               Header="Date 1" 
                                               Width="{Binding DataComandaColWidth, Source={StaticResource DO}, Mode=TwoWay}"
                                               HeaderStyle="{DynamicResource CenterGridHeaderStyle}">

                            <my:DataGridTextColumn.ElementStyle>
                                <Style TargetType="TextBlock">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                    <Setter Property="Margin" Value="5 0"/>                                 
                                </Style>
                            </my:DataGridTextColumn.ElementStyle>
                        </my:DataGridTextColumn>

                        <my:DataGridTextColumn x:Name="Date2" 
                                               CellStyle="{StaticResource MyDataGridCellStyle}" 
                                               Binding="{Binding Path=MyDate2, StringFormat=\{0:dd/MM/yyyy\}}" 
                                               Header="Date 2" 
                                               Width="auto" 
                                               HeaderStyle="{DynamicResource CenterGridHeaderStyle}">
                            <my:DataGridTextColumn.ElementStyle>
                                <Style TargetType="TextBlock">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                    <Setter Property="Margin" Value="5 0"/>                                 
                                </Style>
                            </my:DataGridTextColumn.ElementStyle>
                        </my:DataGridTextColumn>                 

                 </my:DataGrid.Columns>

        </my:DataGrid>            
    </Grid>
</Window>   

Классы :

namespace My.Apps.WPF.TestApp.Classes
{
public class CellDateColorConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values[0] is DateTime && values[1] is DateTime)
        {
            DateTime date1 = (DateTime)values[0];
            DateTime date2 = (DateTime)values[1];                

            if (date1.Date > date2.Date)
            {
                return System.Windows.Media.Brushes.OrangeRed;
            }
        }

        return System.Windows.Data.Binding.DoNothing;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException("CellDateColorConverter is a OneWay converter.");
    }
}

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

}

1 Ответ

0 голосов
/ 26 апреля 2018

Я решил, установив EnableRowVirtualization в False.По умолчанию было установлено значение True.По умолчанию для свойства EnableColumnVirtualization установлено значение False.

Похоже, что использование виртуализированных ячеек влияет на стиль сетки данных в .NET 3.5.Ошибка?Если так, я не знаю, было ли это исправлено в NET 4.0 и выше.

В любом случае, я беспокоюсь об этом, потому что это означает, что я не могу использовать виртуализированные ячейки ... Так что, если у кого-то есть какое-либо другое решение,Пожалуйста, поделитесь здесь.

Другие пользователи сталкивались с такой же проблемой, см. здесь

ОБНОВЛЕНО :

Кроме того, если выЕсли вы хотите сохранить EnableRowVirtualization в True, это можно решить, изменив только режим виртуализации, выполнив следующее:

<DataGrid VirtualizingStackPanel.VirtualizationMode="Standard" />

Проблема заключается в том, что VirtualizationMode по умолчанию имеет значение Recycling, поэтому это вызывает некорректную раскраску строк при прокрутке в виде контейнеров.используются повторно.Это объясняется здесь , как объяснил Эйрик в своем ответе.

...