Вопрос

У меня есть некоторые ячейки в данных, и я хотел бы выделить ячейки в определенных столбцах, когда их значение равна 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)
                               });
    }
  }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top