Настройка фона списка строк и столбцов в WPF

Эта проблема

Я заполняю сетку данных, используя xmlprovider для данных. После загрузки я пытаюсь раскрасить "заблокированные" столбцы и строки на основе списка "заблокированных" строк и столбцов. "Блокировка" - это просто визуальная обратная связь для определенной строки или столбца, которая не используется для дальнейших вычислений. Несмотря на то, что загрузка данных работает нормально, я пробовал разные решения, чтобы установить фоновое свойство строк CERTAIN И столбцов путем циклического прохождения всех ячеек с использованием расширений из расширений сетки данных со смешанным успехом.

Я пытаюсь закрасить ячейки в событии LOADED, но это не всегда работает. И нет события, которое говорит: "Ваши данные были загружены, сэр, хотите что-то сделать сейчас"?

Поэтому мое последнее средство для окрашивания строк и столбцов, вероятно, заключается в использовании установщиков стилей с классом IMultiValueConverter. Но мне не ясно, как я могу отправить правильные данные в конвертер.

Код

Это то, что я имею сейчас:

public partial class MainWindow : Window
{
    public ObservableCollection<Person> MyDynData { get; set; }

    // property representing the locked rows
    public List<int> LockedRows { get; set; }
    // property representing the locked colums
    public List<int> LockedColumns { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        MyDynData = Person.GetData();
        LockedRows = new List<int>{1,3};
        LockedColumns = new List<int>{0};

        DataContext = this;
    }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public static ObservableCollection<Person>GetData()
    {
        return new ObservableCollection<Person>
        {
            new Person {Age = 19, FirstName = "John", LastName = "Gates"},
            new Person {Age = 25, FirstName = "Jill", LastName = "Vegas"},
            new Person {Age = 48, FirstName = "Bill", LastName = "Bates"},
            new Person {Age = 29, FirstName = "Agnes", LastName = "Henderson"},
            new Person {Age = 33, FirstName = "Jenny", LastName = "Giggles"}

        };
    }
}

XAML:

<Window x:Class="DatagridColRowLocker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:converters="clr-namespace:DatagridColRowLocker"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <converters:CellBackgroundConverter x:Key="CellBackgroundConverter"/>
        </Grid.Resources>

        <DataGrid ItemsSource="{Binding Path=MyDynData}" AutoGenerateColumns="True">
            <DataGrid.Resources>
                <Style x:Key="LockedCellStyle" TargetType="DataGridCell">
                    <Style.Setters>
                        <Setter Property="Background">
                            <Setter.Value>
                                <MultiBinding Converter="{StaticResource CellBackgroundConverter}">
                                    <Binding> ??? the current cell</Binding>
                                    <Binding> ??? List of locked columns</Binding>
                                    <Binding> ??? list of locked rows</Binding>
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>
                    </Style.Setters>
                </Style>
            </DataGrid.Resources>
        </DataGrid>
    </Grid>
</Window>

Преобразователь цвета фона ячейки:

class CellBackgroundConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var cell = (DataGridCell)values[0];
        var lockedColumns = (List<int>)values[1];
        var lockedRows = (List<int>)values[2];

        // how to get the row index? 
        var isLocked = lockedColumns.Contains(cell.Column.DisplayIndex);

        return (isLocked) ? new SolidColorBrush(Colors.LightGray) : new SolidColorBrush(Colors.White);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Резюме

  • Как правильно связать мои значения в xaml для работы мультиконвертера
  • Если я передаю ячейку данных в конвертер, я могу получить displaycolIndex, но не rowIndex, как это работает?

2 ответа

Решение

Если вы хотите, чтобы стиль применялся ко всем ячейкам, избавьтесь от x:Key в стиле.

Вот привязки, которые вы просили:

<Style TargetType="DataGridCell">
    <Style.Setters>
        <Setter Property="Background">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource CellBackgroundConverter}">
                    <Binding RelativeSource="{RelativeSource Self}" />
                    <Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext.LockedColumns" />
                    <Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext.LockedRows" />
                    <Binding RelativeSource="{RelativeSource AncestorType=DataGridRow}" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style.Setters>
</Style>

И вот изменения в конвертере:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    var cell = (DataGridCell)values[0];
    var lockedColumns = (List<int>)values[1];
    var lockedRows = (List<int>)values[2];
    var row = (DataGridRow)values[3];

    // how to get the row index? 
    var isLocked = lockedColumns.Contains(cell.Column.DisplayIndex);
    if (!isLocked)
    {
        isLocked = lockedRows.Contains(row.GetIndex());
    }

    return (isLocked) ? new SolidColorBrush(Colors.LightGray) : new SolidColorBrush(Colors.White);
}

В дополнение к принятому ответу вы можете столкнуться с проблемой стиля при выборе строки, как показано на рисунке ниже. Текст на правой стороне "Билла" белый и нечитаемый

введите описание изображения здесь

В этом случае вы можете исправить это, добавив дополнительные параметры ресурса для сетки данных:

<DataGrid.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey }" Color="Black"></SolidColorBrush>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"></SolidColorBrush>
</DataGrid.Resources>
Другие вопросы по тегам