WPF - Как получить ячейку из DataGridRow? - PullRequest
10 голосов
/ 08 сентября 2010

У меня есть DataGrid с привязкой к данным с чередующимися цветами фона строки. Я хотел бы покрасить ячейку по-разному в зависимости от данных, которые она содержит. Я пробовал решение, предлагаемое этой темой

http://wpf.codeplex.com/Thread/View.aspx?ThreadId=51143

Но

DataGridCellsPresenter Presenter = GetVisualChild (строка)

всегда возвращает ноль.

Я использую

    public static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

Но VisualTreeHelper.GetChildrenCount () объекта DataGridRow всегда возвращает 0. Я убедился, что DataGridRow не является нулевым и уже заполнен данными. Любая помощь приветствуется.

Спасибо.

Ответы [ 2 ]

13 голосов
/ 23 января 2014

Если вы знаете свою строку и индекс ячейки, к которой вы хотите получить доступ, то вот как вы можете сделать это в коде:

//here's usage
var cell = myDataGrid.GetCell(row, columnIndex);
if(cell != null)
    cell.Background = Brushes.Green;

Расширение DataGrid:

public static class DataGridExtensions
{
    public static DataGridCell GetCell(this DataGrid grid,  DataGridRow row, int columnIndex = 0)
    {
        if (row == null) return null;

        var presenter = row.FindVisualChild<DataGridCellsPresenter>();
        if (presenter == null) return null;

        var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
        if (cell != null) return cell;

        // now try to bring into view and retreive the cell
        grid.ScrollIntoView(row, grid.Columns[columnIndex]);
        cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);

        return cell;
    }
8 голосов
/ 09 сентября 2010

Прежде всего, не делайте этого в коде позади. Вы боретесь с рамками таким способом. WPF разработан по-другому; Вы должны думать о том, как структура хочет, чтобы вы что-то делали. В случае WPF это классы разметки XAML + конвертер.

Вам нужно две вещи, чтобы достичь того, что вы хотите:

  • Правильная разметка XAML для настройки стиля DataGrid
  • Реализация IValueConverter для перевода значения текста в правильный цвет выделения.

Вот так:

XAML в вашей таблице данных

Первое, что вы хотите сделать, это определить XAML, необходимый для стилизации ваших ячеек DataGrid. Это выглядит так:

<toolkit:DataGrid.CellStyle>
      <Style TargetType="{x:Type toolkit:DataGridCell}">
        <Style.Setters>
          <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource dataGridCellConverter}}" />
        </Style.Setters>
      </Style>
    </toolkit:DataGrid.CellStyle>

Что это делает, это устанавливает привязку к RelativeSource (DataGridCell) и говорит ему использовать Content.Text ячейки в качестве значения для передачи в Converter (dataGridCellConverter).

IValueConverter

Следующее, что вам нужно, это реализация IValueConverter, которая фактически определяет цвета на основе текста ячейки:

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace UserControls.Utility.Converters
{
  public class DataGridCellConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      if (value == null) return Colors.White.ToString();

      if (value.ToString().ToUpper().Contains("CMS")) return "LIME";

      return "ORANGE";
    }

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

Здесь я просто ищу текст "CMS" и окрашиваю фоновую ячейку; если «CMS» не существует, он возвращает оранжевый цвет.

Указать ресурсы

Теперь вам нужно добавить разметку в вашем окне / usercontrol, чтобы указать конвертер как соответствующий ресурс:

<UserControl.Resources>
    <Converters:DataGridCellConverter x:Key="dataGridCellConverter"/>
</UserControl.Resources>

И это должно сделать это! Удачи.

...