Pregunta

Tengo algunas celdas en un datagrid y me gustaría resaltar celdas en ciertas columnas rojo cuando su valor es 0. No estoy seguro de cómo abordar esto.

He mirado esta pregunta: WPF: ¿Cómo resaltar todas las celdas de un DataGrid que cumple con una condición? Pero ninguna de las soluciones me ha funcionado.

Con el uso de desencadenantes de estilo, parece que los desencadenantes están destinados a aplicarse en las propiedades. Cuando hago algo como si nada pasa (supongo porque hay más en el contenido que un valor simple).

Con la última solución sugerida, estaba obteniendo un problema de tiempo de compilación que parecía ser una manifestación de un error que ha estado en VS por un tiempo: La clase de encuadernación personalizada no funciona correctamente

¿Alguna idea de cómo puedo lograr esto?

¿Alguien tiene alguna idea?

¿Fue útil?

Solución

La mejor manera de cambiar el color de fondo de una celda basado en el valor de una ceca DataGrid es definir una plantilla de datos para DataGridTemplateColumn con un convertidor para alterar el color de fondo de la celda. La muestra proporcionada aquí usa MVVM.

Las partes de las teclas para buscar en el siguiente ejemplo incluyen:

1: XAML que convierte un entero (factor) en el modelo a un color:

<TextBlock Text="{Binding Path=FirstName}" 
           Background="{Binding Path=Factor, 
             Converter={StaticResource objectConvter}}" />

2: Converter que devuelve un SolidColorBrush basado en una propiedad entera en el modelo:

public class ObjectToBackgroundConverter : IValueConverter

3: ViewModel que cambia el valor entero en el modelo entre 0 y 1 desde un botón Haga clic para disparar un evento que cambia el color en el convertidor.

private void OnChangeFactor(object obj)
{
  foreach (var customer in Customers)
  {
    if ( customer.Factor != 0 )
    {
      customer.Factor = 0;
    }
    else
    {
      customer.Factor = 1;
    }
  }
}

4: Modelo implementa inotifypropertychanged utilizada para disparar el evento para alterar el color de fondo llamando a OnPropertyChanged

private int _factor = 0;
public int Factor
{
  get { return _factor; }
  set
  {
    _factor = value;
    OnPropertyChanged("Factor");
  }
}

He proporcionado todos los bits necesarios aquí en mi respuesta con la excepción de las piezas centrales utilizadas como base del patrón MVVM que incluye ViewModelBase (inotifyPropertyChanged) y delegateCommand que puede encontrar en Google. Tenga en cuenta que encuentro el DataContext de la vista al Modelo ViewModel en el constructor de código-behind. Puedo publicar estos bits adicionales si es necesario.

Aquí está el 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>

Aquí está el convertidor:

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();
    }
  }
}

Aquí está el Modelo View:

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;
    }
  }
}

Aquí está el modelo:

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)
                               });
    }
  }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top