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

WPF-如何从DataGridRow获取单元格?,wpf,datagrid,datagridcell,Wpf,Datagrid,Datagridcell,我有一个数据绑定的DataGrid,具有交替的行背景色。我想根据单元格包含的数据为其添加不同的颜色。我已经尝试过这条线索所建议的解决方案 但是, DataGridCellsPresenter=GetVisualChild(行) 始终返回null 我正在使用 public static T GetVisualChild<T>(Visual parent) where T : Visual { T child = default(T);

我有一个数据绑定的DataGrid,具有交替的行背景色。我想根据单元格包含的数据为其添加不同的颜色。我已经尝试过这条线索所建议的解决方案

但是,

DataGridCellsPresenter=GetVisualChild(行)

始终返回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;
    }
public static T GetVisualChild(可视父对象),其中T:Visual
{
T child=默认值(T);
int numVisuals=VisualTreeHelper.GetChildrenCount(父级);
对于(int i=0;i
但是DataGridRow的VisualTreeHelper.GetChildrenCount()始终返回0。我已经验证了DataGridRow不是null,并且已经填充了数据。感谢您的帮助


谢谢。

首先,不要在代码隐藏中执行此操作。您正在用这种方式与框架作斗争。WPF的设计不同;你必须考虑框架希望你做什么。对于WPF,它是XAML标记+转换器类

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

  • 设置DataGrid样式的适当XAML标记
  • 一个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>
在这里,我只是寻找文本“CMS”和着色的背景细胞;如果“CMS”不存在,则返回橙色

指定资源

现在,您需要在窗口/用户控件中添加标记,以将转换器指定为适当的资源:

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


这就应该做到了!祝你好运

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

//here's usage
var cell = myDataGrid.GetCell(row, columnIndex);
if(cell != null)
    cell.Background = Brushes.Green;
数据网格扩展:

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;
    }
公共静态类DataGridExtensions
{
公共静态DataGridCell GetCell(此DataGrid网格,DataGridRow行,int columnIndex=0)
{
if(row==null)返回null;
var presenter=row.FindVisualChild();
if(presenter==null)返回null;
var cell=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
如果(单元格!=null)返回单元格;
//现在试着把手机放在视野里,然后拿回手机
grid.ScrollIntoView(行,grid.Columns[columnIndex]);
单元格=(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
返回单元;
}

这才是真正的答案。我正在尝试类似的方法,但似乎不起作用。你能检查一下这个主题吗?如果你在答案中添加以下内容,那就好了。“在WPF的情况下,它是XAML标记+转换器类。”-这是你个人的看法
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;
    }