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
Looping Through WPF DataGrid Using foreach
提问by MoonKnight
All, I am attempting to loop through a WPF DataGrid
using 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 Background
colour of a row in my DataGrid
I need to work with the DataGridRow
object ascociated with the DataRowView
rv
.
问题是,为了更改Background
我的行的颜色,DataGrid
我需要DataGridRow
使用与DataRowView
rv
.
How do I get a reference to the DataGridRow
from 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 ItemContainerGenerator
to 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