C# 使用 foreach 循环遍历 WPF DataGrid

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15657348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:30:40  来源:igfitidea点击:

Looping Through WPF DataGrid Using foreach

c#wpfdatagridtype-conversion

提问by MoonKnight

All, I am attempting to loop through a WPF DataGridusing a for each loop to change the background colour of erroneous cells. I have checked many questions but I have yet to find a sufficient answer. What I have so far is

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

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

The problem is that in order to change the Backgroundcolour of a row in my DataGridI need to work with the DataGridRowobject ascociated with the DataRowViewrv.

问题是,为了更改Background我的行的颜色,DataGrid我需要DataGridRow使用与DataRowViewrv.

How do I get a reference to the DataGridRowfrom the object rv(DataRowView)?

如何DataGridRow从对象rv( DataRowView)获取对 的引用?

Thanks for your time.

谢谢你的时间。

Edit. Based upon the advice below I now have the following style which works with the mouse over event and set the back and fore font of the relevant cell. However, I am really lost as to how to apply the backcolor to a cell at run-time in my code above. The XML style is

编辑。根据下面的建议,我现在有以下样式,它适用于鼠标悬停事件并设置相关单元格的前后字体。但是,我真的不知道如何在上面的代码中在运行时将背景色应用于单元格。XML 样式是

<Window.Resources>
    <Style TargetType="{x:Type DataGridRow}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver"
                     Value="True">
                <Setter Property="Background" Value="Red" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

采纳答案by Tigran

When you're working with WPF, avoid alwaysaccessing UI artifacts directly.

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

Create in you ModelView a property Color, and bind it to the background color of a single row template of your DataGrid view.

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

So in order to change the color you will loop throw the ModelView collecton and set/read Color property of every single object binded to every single row. By changing it, if binding is correctly settuped, you will affect row UI color appearance.

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

For concrete sample you can look on:

对于具体示例,您可以查看:

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

如何将数据网格行的背景绑定到特定颜色?

回答by Rohit Vats

You can use the ItemContainerGeneratorto get the visual representation for your data i.e. DataGridRow-

您可以使用ItemContainerGenerator来获取数据的可视化表示,即DataGridRow-

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

回答by MoonKnight

After much reading I have found a way to do what I wanted - colour cells at run-time depending on certain conditions. This is the method I use to do the colouring

经过大量阅读后,我找到了一种方法来做我想做的事情 - 根据某些条件在运行时为单元格着色。这是我用来做着色的方法

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

These are the associated utility methods required

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

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

Note however, that the colour of the cells move from cell to cell when the user scrolls!? This is yet another amazing annoyance of WPF. I am really confused over why something this simple can be made so so difficult. The suggestion that we need to use a MVVM-type pattern for this kind of thing I find amazing...

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

I hope this helps someone else.

我希望这对其他人有帮助。

回答by MSTr

the answer of "Killercam" worked for me but i needed to add :

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

myDataGrid.UpdateLayout();

myDataGrid.UpdateLayout();

before using the GetCell methods so i'm sure i'm not getting a null reference.

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

to get the whole Helper class look at DataGridHelper

让整个 Helper 类看看DataGridHelper

after all that pain, i try the whole code and i faced another probem wich is that the correctly colored cells changed during a scroll, the solution was to enable Virtualization and set its mode to Standard.

在经历了这么多痛苦之后,我尝试了整个代码,但我遇到了另一个问题,即在滚动期间正确着色的单元格发生了变化,解决方案是启用虚拟化并将其模式设置为标准。

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

so, hope this will help any one who will need to iterate through datagrid cells.

所以,希望这能帮助任何需要遍历数据网格单元的人。

回答by yudhi

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