【问题标题】:WPF - How to get a cell from a DataGridRow?WPF - 如何从 DataGridRow 中获取单元格?
【发布时间】:2011-04-09 22:02:03
【问题描述】:

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

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

但是,

DataGridCellsPresenter 演示者 = 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 不为空并且已经填充了数据。任何帮助表示赞赏。

谢谢。

【问题讨论】:

    标签: wpf datagrid datagridcell


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    首先,不要在代码隐藏中执行此操作。你正在用这种做事方式与框架作斗争。 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 作为传递给转换器(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.Resources>
        <Converters:DataGridCellConverter x:Key="dataGridCellConverter"/>
    </UserControl.Resources>
    

    应该这样做!祝你好运。

    【讨论】:

    • '对于 WPF,它是 XAML 标记 + 转换器类。' - 这是你个人的看法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多