Изменить фон DataGridCell в соответствии с его содержимым

Я знаю, что мой вопрос уже был задан и на него здесь уже было дано несколько ответов. Но я просто не могу заставить его работать так, как я хотел бы. Как указано в заголовке, я пытаюсь изменить цвет фона моей ячейки данных в зависимости от ее содержимого. Я относительно новичок в WPF, но я думаю, что решение - это конвертер в сочетании с привязкой. Цель состоит в том, чтобы изменить цвет фона ячейки в зависимости от свойства, называемого «Статус», которое представляет собой перечисление с четырьмя состояниями.

Я уже написал конвертер:

using System;
using System.Windows.Data;
using System.Drawing;
using System.Windows;

namespace Admin
{
    [ValueConversion(typeof(Member.UserStatus), typeof(Brushes))]
    public class StatusToColorConverter : IValueConverter
    {
        #region IValueConverter Member

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var enumValue = (Member.UserStatus)value;

            if(enumValue == Member.UserStatus.Change)
                return Brushes.Red;
            if(enumValue == Member.UserStatus.Import)
                return Brushes.Blue;
            if(enumValue == Member.UserStatus.Remove)
                return Brushes.Orange;
            if(enumValue == Member.UserStatus.Synced)
                return Brushes.Green;
            else
                return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

Все идет нормально. Часть xaml выглядит так (после некоторого поиска в Google...)

<DataGrid.Columns>              
    <DataGridTemplateColumn Header="Status">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Status}" Background="{Binding Status, Converter={StaticResource StatusToColorConverter}}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns> 

Я действительно не понимаю (пока), что такое DataGridTemplateColums и DataTemplates. Но я пробовал то же самое с CellStyle и другим способом, который я не могу вспомнить. Преобразователь имеет точку останова и вызывается во всех решениях, которые я пробовал. Но каким-то образом свойство «Фон», похоже, игнорирует возвращаемое преобразователем значение. Так что я предполагаю, что моя ошибка (или мое непонимание) имеет другой источник.

Кто-нибудь хочет указать мне правильное направление?


person SKull    schedule 16.07.2013    source источник
comment
Что делает ваше текущее решение, выбирает ли он полную строку? Вы пытались установить SelectionUnit=Cell для datargid и стилизовать DataGridCell?   -  person Nitesh    schedule 16.07.2013
comment
стилизация ячейки была одним из решений, которые я пробовал (по крайней мере, я так думаю), тот же результат: конвертер вызывается, но свойство фона игнорирует значение. Не могли бы вы опубликовать (или дать ссылку) пример того, как такой стиль DataGridCell может выглядеть в XAML?   -  person SKull    schedule 16.07.2013
comment
попробуйте две вещи: 1- Работает ли привязка? попробуйте точку останова в конвертере и посмотрите, получит ли 'enumValue' желаемое значение. 2- просмотрите окно вывода во время работы в режиме отладки, чтобы увидеть любое связанное сообщение.   -  person Naser Asadi    schedule 16.07.2013
comment
@Насер Асади: да. Привязка работает таким образом, что, по крайней мере, преобразователь получает и возвращает правильные значения. Просто кажется, что возвращаемая кисть игнорируется свойством фона. Спасибо за подсказку относительно окна вывода. Я часто забываю об этом. Однако он не выводит никаких сообщений об ошибках.   -  person SKull    schedule 16.07.2013


Ответы (3)


Если я правильно интерпретирую ваш XAML, вы рисуете столбец HEADER («самая верхняя» ячейка), а не саму ячейку.

Это работает для меня:

<DataGrid.CellStyle>
                <Style TargetType="{x:Type DataGridCell}">
                    <Setter Property="Background" Value="{Binding Status},
                       Converter={StaticResource StatusToColorConverter}">
                    </Setter>
                </Style>
</DataGrid.CellStyle>

Это должно покрасить вашу камеру

В качестве примечания: ваши ячейки могут выглядеть «странно», если вы рисуете их фон — мои ячейки часто теряют свои границы и т. д. Быстрое и простое решение — добавить следующие установщики свойств (это стиль wpf по умолчанию)

 <Setter Property="BorderThickness" Value="1,0,1,1"></Setter>
 <Setter Property="BorderBrush" Value="#FF000000"></Setter>
person Christian Sauer    schedule 16.07.2013
comment
Я только что перечитал ваш код: вы хотите нарисовать только столбец STATUS, но не другой столбец? Если это так, вам нужен Multibinding - у меня есть код для него, так что скажите, если вам это нужно. - person Christian Sauer; 16.07.2013
comment
Вы имеете в виду: ` ‹DataGrid.CellStyle› ‹Style TargetType={x:Type DataGridCell}› ‹Setter Property=Background Value={Binding Status, Converter={StaticResource StatusToColorConverter}}› ‹/Setter› ‹/Style› ‹/ DataGrid.CellStyle›` ? Тоже не работает. - person SKull; 16.07.2013
comment
Я хочу рисовать ячейки в столбце «Статус» индивидуально в отношении их содержимого. - person SKull; 16.07.2013
comment
Извините за то, что это не работает. Что ж, вызывается преобразователь с правильными значениями, и он даже возвращает правильную кисть... Но все то же самое: кисть, кажется, игнорируется. - person SKull; 16.07.2013

Я сделал это следующим образом:

              <DataGrid.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="Background">
                            <Setter.Value>
                                <Binding Path="Row" Mode="OneWay" />
                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGrid.CellStyle>

Обратите внимание, что я использую DataView как ItemsSource для DataGrid и поэтому привязываюсь к «Row». Элемент — это, по сути, DataRowView. Затем вам нужно получить доступ к значениям строк в конвертере:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        var enumValue = (Member.UserStatus)((DataRow)value)["Status"];
        if(enumValue == Member.UserStatus.Change)
            return Brushes.Red;
        if(enumValue == Member.UserStatus.Import)
            return Brushes.Blue;
        if(enumValue == Member.UserStatus.Remove)
            return Brushes.Orange;
        if(enumValue == Member.UserStatus.Synced)
            return Brushes.Green;
        else
            return DependencyProperty.UnsetValue;
    }
person Vale    schedule 16.07.2013
comment
Где мне реализовать конвертер в этом решении? Синтаксис XAML все еще сбивает меня с толку. - person SKull; 16.07.2013
comment
@Mathew Хорошо, как ты реализовал это в своем случае? Делайте это так же. - person Vale; 16.07.2013

Хорошо, парни. У меня сейчас проблема решена. Проблема была не в моем коде xaml. Преобразователь тоже работал нормально. Проблема заключалась в следующей строке в файле конвертера .cs:

    using System.Drawing;

Я заменил его на правильный:

    using System.Windows.Media;

И теперь это работает как шарм. ... Я передавал кисти для WinForms вместо кистей WPF!

Спасибо за помощь в любом случае :)

person SKull    schedule 16.07.2013
comment
Ух ты. Забавно, что никто этого не заметил :) - person Vale; 16.07.2013