WPF - 如何从DataGridRow获取单元格?

时间:2010-09-08 18:56:44

标签: wpf datagrid datagridcell

我有一个数据绑定的DataGrid,具有交替的行背景颜色。我想根据它包含的数据对单元格进行不同的着色。我尝试过这个线程建议的解决方案

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

但是,

DataGridCellsPresenter presenter = GetVisualChild(row)

始终返回null。

我正在使用

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

但DataGridRow的VisualTreeHelper.GetChildrenCount()始终返回0.我已经验证DataGridRow不为null并且已经填充了数据。任何帮助表示赞赏。

感谢。

2 个答案:

答案 0 :(得分:12)

如果您知道要访问的单元格的行和索引,那么您可以在代码中执行此操作:

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

答案 1 :(得分:8)

首先,不要在代码隐藏中执行此操作。你用这种做事方式来对抗框架。 WPF的设计不同;你必须考虑框架如何要你做事。在WPF的情况下,它是XAML标记+转换器类。

你需要两件事来实现你想要的目标:

  • 正确的XAML标记以设置DataGrid的样式
  • IValueConverter实现,用于将文本的值转换为正确的高亮颜色。

这里是:

数据网格中的XAML

您要做的第一件事是定义为​​DataGrid单元格设置样式所需的XAML。它看起来像这样:

<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”不存在,则返回橙色。

指定资源

现在,您需要在window / usercontrol中添加标记,以将转换器指定为适当的资源:

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

应该这样做!祝好运。