使用foreach循环通过WPF DataGrid

时间:2013-03-27 11:07:33

标签: c# wpf datagrid type-conversion

所有,我试图使用for循环来遍历WPF DataGrid以更改错误单元格的背景颜色。我检查了很多问题,但我还没有找到足够的答案。到目前为止我所拥有的是

public void RunChecks()
{
    const int baseColumnCount = 3;
    foreach (DataRowView rv in dataGrid.Items)
    {
        for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++)
        {
            if (!CheckForBalancedParentheses(rv.Row[i].ToString()))
            {
                Color color = (Color)ColorConverter.ConvertFromString("#FF0000");
                row.Background = new SolidColorBrush(color); // Problem!
            }
        }
    }
}

问题是,为了更改Background中某行的DataGrid颜色,我需要使用与DataGridRow {{相关联的DataRowView对象1}}。

如何从对象rvDataGridRow)获取对rv的引用?

感谢您的时间。

编辑。根据下面的建议,我现在有以下样式,它与鼠标悬停在事件上并设置相关单元格的后退和前导字体。但是,我真的迷失了如何在上面的代码中在运行时将backcolor应用到单元格。 XML样式是

DataRowView

5 个答案:

答案 0 :(得分:5)

当您使用WPF时,避免始终直接访问UI工件。

在ModelView中创建属性Color,并将其绑定到DataGrid视图的单行模板的背景颜色。

因此,为了更改颜色,您将循环抛出ModelView collecton并设置/读取绑定到每一行的每个对象的Color属性。通过更改它,如果正确设置了绑定,则会影响行UI颜色外观。

对于具体样本,您可以查看:

How do I bind the background of a data grid row to specific color?

答案 1 :(得分:2)

您可以使用ItemContainerGenerator获取数据的直观表示,例如DataGridRow -

DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator
                                       .ContainerFromItem(rv);

答案 2 :(得分:1)

“Killercam”的答案对我有用,但我需要补充一下:

myDataGrid.UpdateLayout();

在使用GetCell方法之前所以我确定我没有得到空引用。

让整个Helper课程看DataGridHelper

在经历了所有的痛苦之后,我尝试了整个代码,我面临另一个问题,即在滚动过程中正确着色的单元格发生了变化,解决方案是启用虚拟化并将其模式设置为标准。

VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard"

所以,希望这将有助于任何需要迭代数据网格单元的人。

答案 3 :(得分:0)

经过多次阅读后,我找到了一种方法来做我想要的 - 在运行时根据特定条件对彩色单元格进行处理。这是我用来进行着色的方法

public void RunChecks()
{
    const int baseColumnCount = 3;
    for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++)
    {
        foreach (DataGridRow row in Utilities.GetDataGridRows(dataGrid))
        {
            if (row != null)
            {
                DataGridCell cell = dataGrid.GetCell(row, i);

                // Start work with cell.
                Color color;
                TextBlock tb = cell.Content as TextBlock;
                string cellValue = tb.Text;
                if (!CheckForBalancedParentheses(cellValue))
                    color = (Color)ColorConverter.ConvertFromString("#FF0000");
                else
                    color = (Color)ColorConverter.ConvertFromString("#FFFFFF");
                row.Background = new SolidColorBrush(color);
                //cell.Background = new SolidColorBrush(color);
            }
        }
    }
}

这些是所需的相关实用程序方法

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 DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
    if (row != null)
    {
        DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
        if (presenter == null)
        {
            grid.ScrollIntoView(row, grid.Columns[column]);
            presenter = GetVisualChild<DataGridCellsPresenter>(row);
        }
        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
        return cell;
    }
    return null;
}

public static IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
    var itemsSource = grid.ItemsSource as IEnumerable;
    if (null == itemsSource) yield return null;
    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
        if (null != row) yield return row;
    }
}

但请注意,当用户滚动时,细胞的颜色会从一个细胞移动到另一个细胞!这是WPF的另一个令人惊讶的烦恼。我真的很困惑为什么这么简单的事情会如此困难。建议我们需要使用MVVM类型的模式来发现这种事情我觉得很棒...

我希望这有助于其他人。

答案 4 :(得分:0)

//the Class that resembles the Datagrid Item schema

foreach (Class cl in dgDatagrid.Items)
   {
       MessageBox.Show(cl.ID.ToString());
   }

this is the most simplest way to read the datagrid data
most articles misguide such simple things