Триггер на основе значения DataGridCell
-
27-10-2019 - |
Вопрос
У меня есть некоторые ячейки в данных, и я хотел бы выделить ячейки в определенных столбцах, когда их значение равна 0. Я не уверен, как приблизиться к этому.
Я посмотрел на этот вопрос: WPF: Как выделить все ячейки DataGrid, соответствующего условию? Но ни одно из решений не сработало для меня.
При использовании триггеров стиля кажется, что триггеры предназначены для применения на свойствах. Когда я делаю что -то вроде ничего, что не происходит (я предполагаю, потому что в контенте есть нечто большее, чем простое значение).
С последним предложенным решением я получал проблему во время компиляции, которая, казалось, была проявлением ошибки, которая была в VS уже некоторое время: Пользовательский класс привязки работает неправильно
Есть идеи, как я могу этого добиться?
У кого -нибудь есть идеи?
Решение
Лучший способ изменить цвет фона ячейки на основе значения DataGridCell - это определить DataTemplate для DataGridTemplateColumn с преобразователем, чтобы изменить цвет фона ячейки. В образце, предоставленном здесь, используется MVVM.
Части ключей для поиска в следующем примере включают:
1: XAML, который преобразует целое число (фактор) в модели в цвет:
<TextBlock Text="{Binding Path=FirstName}"
Background="{Binding Path=Factor,
Converter={StaticResource objectConvter}}" />
2: преобразователь, который возвращает SolidColorbrush на основе целочисленного свойства в модели:
public class ObjectToBackgroundConverter : IValueConverter
3: ViewModel, которая изменяет целочисленное значение в модели от 0 до 1 из кнопки, нажмите, чтобы запустить событие, которое изменяет цвет в преобразователе.
private void OnChangeFactor(object obj)
{
foreach (var customer in Customers)
{
if ( customer.Factor != 0 )
{
customer.Factor = 0;
}
else
{
customer.Factor = 1;
}
}
}
4: Модель реализует inotifypropertychanged, используемый для увольнения события, чтобы изменить цвет фона, призывая Propertychanged
private int _factor = 0;
public int Factor
{
get { return _factor; }
set
{
_factor = value;
OnPropertyChanged("Factor");
}
}
Я предоставил все биты, необходимые здесь в моем ответе, за исключением основных деталей, используемых в качестве основы шаблона MVVM, который включает в себя ViewModelbase (inotifyPropertyChanged) и DelegateCommand, которую вы можете найти в Google. Обратите внимание, что я привязываю DataContext представления с ViewModel в конструкторе кода. Я могу опубликовать эти дополнительные биты, если это необходимо.
Вот XAML:
<Window x:Class="DatagridCellsChangeColor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:DatagridCellsChangeColor.Converter"
Title="MainWindow"
Height="350" Width="525">
<Window.Resources>
<Helpers:ObjectToBackgroundConverter x:Key="objectConvter"/>
/Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content="Change Factor" Command="{Binding Path=ChangeFactor}"/>
<DataGrid
Grid.Row="1"
Grid.Column="0"
Background="Transparent"
ItemsSource="{Binding Customers}"
IsReadOnly="True"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn
Header="First Name"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=FirstName}"
Background="{Binding Path=Factor,
Converter={StaticResource objectConvter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Header="Last Name"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=LastName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Вот конвертер:
using System;
using System.Drawing;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
using Brushes = System.Windows.Media.Brushes;
namespace DatagridCellsChangeColor.Converter
{
[ValueConversion(typeof(object), typeof(SolidBrush))]
public class ObjectToBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int c = (int)value;
SolidColorBrush b;
if (c == 0)
{
b = Brushes.Gold;
}
else
{
b = Brushes.Green;
}
return b;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Вот ViewModel:
using System.Collections.ObjectModel;
using System.Windows.Input;
using DatagridCellsChangeColor.Commands;
using DatagridCellsChangeColor.Model;
namespace DatagridCellsChangeColor.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
ChangeFactor = new DelegateCommand<object>(OnChangeFactor, CanChangeFactor);
}
private ObservableCollection<Customer> _customers = Customer.GetSampleCustomerList();
public ObservableCollection<Customer> Customers
{
get
{
return _customers;
}
}
public ICommand ChangeFactor { get; set; }
private void OnChangeFactor(object obj)
{
foreach (var customer in Customers)
{
if ( customer.Factor != 0 )
{
customer.Factor = 0;
}
else
{
customer.Factor = 1;
}
}
}
private bool CanChangeFactor(object obj)
{
return true;
}
}
}
Вот модель:
using System;
using System.Collections.ObjectModel;
using DatagridCellsChangeColor.ViewModel;
namespace DatagridCellsChangeColor.Model
{
public class Customer : ViewModelBase
{
public Customer(String first, string middle, String last, int factor)
{
this.FirstName = first;
this.MiddleName = last;
this.LastName = last;
this.Factor = factor;
}
public String FirstName { get; set; }
public String MiddleName { get; set; }
public String LastName { get; set; }
private int _factor = 0;
public int Factor
{
get { return _factor; }
set
{
_factor = value;
OnPropertyChanged("Factor");
}
}
public static ObservableCollection<Customer> GetSampleCustomerList()
{
return new ObservableCollection<Customer>(new Customer[4]
{
new Customer("Larry", "A", "Zero", 0),
new Customer("Bob", "B", "One", 1),
new Customer("Jenny", "C", "Two", 0),
new Customer("Lucy", "D", "THree", 2)
});
}
}
}