Як встановити фон рядка DataGrid на основі значення властивості за допомогою прив’язок даних


81

У своєму коді XAML я хочу встановити Backgroundколір кожного рядка на основі значення об'єкта в одному конкретному рядку. У мене є ObservableCollectionз z, і кожен з zмає властивість State. Я почав з чогось такого у своєму DataGrid:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Background" 
                Value="{Binding z.StateId, Converter={StaticResource StateIdToColorConverter}}"/>
     </Style>
</DataGrid.RowStyle>

Це неправильний підхід, оскільки x не є властивістю в моєму класі ViewModel.

У моєму класі ViewModel у мене є , ObservableCollection<z>який є ItemsSourceцим DataGrid, і SelectedItemтипу z.

Я міг би прив'язати колір до SelectedItem, але це змінить лише один рядок у DataGrid.

Як я можу на основі однієї властивості змінити ці рядки backgroundcolor?

Відповіді:


171

Використовуйте DataTrigger:

<DataGrid ItemsSource="{Binding YourItemsSource}">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow"> 
            <Style.Triggers>
                <DataTrigger Binding="{Binding State}" Value="State1">
                    <Setter Property="Background" Value="Red"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding State}" Value="State2">
                    <Setter Property="Background" Value="Green"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

2
Я отримую лише: Помилка шляху BindingExpression: Як 'State' property not found on 'object' ''z' (HashCode=7162954)'. BindingExpression:Path=State; DataItem='z' (HashCode=7162954); target element is 'DataGridRow' (Name=''); target property is 'NoTarget' (type 'Object')це, що він не знаходить стану власності, коли мій об'єкт тримає це, а моя база даних відображає стан як стовпець?
Тобіас Мо Торстенсен

2
Я сподіваюся, ви робите це не так z.State.
Нітеш

4
Просто натрапив на це ще раз після відпустки з wpf, бажаю, щоб я міг знову проголосувати!
Ric

5
Це чудово. У рішенні, де я його використовував, мені потрібно було змінити стан на основі enumзначення. Ця відповідь на StackOverflow допомогла мені в цьому.
kaspermoerch

Не забувайте, що має бути майно, до якого ви зобов'язуєтесьpublic
хлопець із CAD

17

Те ж саме можна зробити і DataTriggerзанадто:

 <DataGrid.RowStyle>
     <Style TargetType="DataGridRow">
         <Setter Property="Background" >
             <Setter.Value>
                 <Binding Path="State" Converter="{StaticResource BooleanToBrushConverter}">
                     <Binding.ConverterParameter>
                         <x:Array Type="SolidColorBrush">
                             <SolidColorBrush Color="{StaticResource RedColor}"/>
                             <SolidColorBrush Color="{StaticResource TransparentColor}"/>
                         </x:Array>
                     </Binding.ConverterParameter>
                 </Binding>
             </Setter.Value>
         </Setter>
     </Style>
 </DataGrid.RowStyle>

Де BooleanToBrushConverterзнаходиться наступний клас:

public class BooleanToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Brushes.Transparent;

        Brush[] brushes = parameter as Brush[];
        if (brushes == null)
            return Brushes.Transparent;

        bool isTrue;
        bool.TryParse(value.ToString(), out isTrue);

        if (isTrue)
        {
            var brush =  (SolidColorBrush)brushes[0];
            return brush ?? Brushes.Transparent;
        }
        else
        {
            var brush = (SolidColorBrush)brushes[1];
            return brush ?? Brushes.Transparent;
        }
    }

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

Ще кращим є застосування IMultiValueConverter ( docs.microsoft.com/en-us/dotnet/api/… ), щоб просто прив’язати більше одного властивості і забезпечити, щоб перетворювач повернув правильний колір для стану цих кількох властивостей (я опускаю зразок, оскільки він справді схожий на звичайний корпус перетворювача, але я можу розмістити його, якщо він комусь знадобиться)
user8276908

7

У XAML додайте та визначте властивість RowStyle для DataGrid з метою встановити фон рядка до кольору, визначеного в моєму об'єкті співробітника.

<DataGrid AutoGenerateColumns="False" ItemsSource="EmployeeList">
   <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
             <Setter Property="Background" Value="{Binding ColorSet}"/>
        </Style>
   </DataGrid.RowStyle>

І в моєму класі працівників

public class Employee {

    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public string ColorSet { get; set; }

    public Employee() { }

    public Employee(int id, string name, int age)
    {
        Id = id;
        Name = name;
        Age = age;
        if (Age > 50)
        {
            ColorSet = "Green";
        }
        else if (Age > 100)
        {
            ColorSet = "Red";
        }
        else
        {
            ColorSet = "White";
        }
    }
}

Таким чином , кожна рядок DataGrid має колір фону в ColorSet власності мого об'єкта .


Мені подобається цей метод, оскільки колір об'єкта централізований у самій моделі, а не у вигляді.
ΩmegaMan

1
За винятком того, що це порушує MVVM. Якщо вам все одно, майте на це справу. Але досвід користувача не повинен визначатися моделлю. Це робота View / View Model
BrianVPS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.