C# WPF 遍历数据网格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15686381/
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
WPF iterate through datagrid
提问by lemunk
Using WPF C#.NET4.5 using visual studio 2012 ulti.
使用 Visual Studio 2012 ulti 使用 WPF C#.NET4.5。
Old winforms code:
旧的winforms代码:
foreach (DataGridViewRow paretoRow in ParetoGrid.Rows)
{
if ((Convert.ToInt32(paretoRow.Cells["CurrentPareto"].Value) < (Convert.ToInt32(paretoRow.Cells["NewPareto"].Value))))
{
paretoRow.Cells["pNew"].Value = downArrow
}
}
As you can see each row I cycle through I check a specific cell, if true I then populate another cell. This was good old winforms code I used many times before...however. Switching over to WPF was alot more different than i previously assumed.
如您所见,我循环遍历的每一行都会检查一个特定的单元格,如果为真,则填充另一个单元格。这是我以前使用过很多次的很好的旧 winforms 代码……但是。切换到 WPF 与我之前假设的不同。
DataGrid
does not contain the Row
property. Instead, I think you need to use:
DataGrid
不包含该Row
属性。相反,我认为您需要使用:
DataGridRow paretoRow in paretogrid.Items
But im still at a loss on who to now get the cell.
但我仍然不知道现在该由谁来获得细胞。
So my question is, is there syntax changes to perform, if so where? Or as I'm beginning to believe datagrids in WPF operate with Objects more so than winforms thus not needing to use a propertie called "row", if this is the case what logic/syntax should i know use in this example?
所以我的问题是,是否有语法更改要执行,如果有,在哪里?或者因为我开始相信 WPF 中的数据网格比 winform 更能使用对象操作,因此不需要使用名为“行”的属性,如果是这种情况,我应该知道在这个示例中使用什么逻辑/语法?
Thanks for your patience guys, think when I go home for the bank holiday I'll do a bit of WPF digging to see how different it actually is.
感谢你们的耐心,想想当我回家过银行假期时,我会做一些 WPF 挖掘,看看它实际上有多大不同。
采纳答案by COLD TOLD
I think first think you want to do is to get all rows of your DataGrid
:
我认为首先认为您想要做的是获取您的所有行DataGrid
:
public IEnumerable<Microsoft.Windows.Controls.DataGridRow> GetDataGridRows(Microsoft.Windows.Controls.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 Microsoft.Windows.Controls.DataGridRow;
if (null != row) yield return row;
}
}
and then iterate through your grid:
然后遍历您的网格:
var rows = GetDataGridRows(nameofyordatagrid);
foreach (DataGridRow row in rows)
{
DataRowView rowView = (DataRowView)row.Item;
foreach (DataGridColumn column in nameofyordatagrid.Columns)
{
if (column.GetCellContent(row) is TextBlock)
{
TextBlock cellContent = column.GetCellContent(row) as TextBlock;
MessageBox.Show(cellContent.Text);
}
}
回答by Patrick
In WPF you go about it a lot more dynamic and ObjectOrientated. You can bind the Column "pNew" on a Property of the element you put in the DataGrid
, which returns downarrow.
If the value changes you can raise the Event PropertyChanged
(Interface INotifyPropertyChanged
) and the bound Property will get reevaluated.
在 WPF 中,您会更加动态和面向对象。您可以在您放入的元素的属性上绑定列“pNew”,该属性DataGrid
返回向下箭头。如果值发生变化,您可以引发事件PropertyChanged
(接口INotifyPropertyChanged
)并且绑定的属性将被重新评估。
Also interesting for beginning with WPF is DataTemplate
, ControlTemplate
, Converter
.
Converter changes the Property Value to a usable Value for WPF (e.g. BoolToVisibility) when the Property gets called.
DataTemplate
and ControlTemplate
can be used to alter the appearance of the Control.
从 WPF 开始也很有趣的是DataTemplate
, ControlTemplate
, Converter
。当属性被调用时,转换器将属性值更改为 WPF 的可用值(例如 BoolToVisibility)。
DataTemplate
并且ControlTemplate
可以用来改变控制的外观。
There are several good Tutorials for WPF out there. I would also recommend to look into the MVVM-Pattern to use as a between layer of your Businessobject and your WPF-Control, especially to handle things like what you try to do here.
有几个很好的 WPF 教程。我还建议研究 MVVM-Pattern 以用作 Businessobject 和 WPF-Control 的中间层,尤其是处理诸如您在此处尝试执行的操作之类的事情。
回答by Nick Freeman
Yes, you are right. WPF DataGrid
is built around better supporting the use of objects.
你是对的。WPFDataGrid
是围绕更好地支持对象的使用而构建的。
You could use a ViewModel similar to the following. Build them all into a collection and then set that collection as your ItemsSource
. You would also need to use a ValueConverter if you want to display and image instead of a checkmark for pNew being true/false.
您可以使用类似于以下内容的 ViewModel。将它们全部构建到一个集合中,然后将该集合设置为您的ItemsSource
. 如果要显示图像而不是 pNew 为 true/false 的复选标记,则还需要使用 ValueConverter。
public class FooViewModel : INotifyPropertyChanged
{
private int currentPareto;
public int CurrentPareto
{
get
{
return currentPareto;
}
set
{
if (currentPareto == value)
return;
currentPareto = value;
OnPropertyChanged("CurrentPareto");
OnPropertyChanged("pNew");
}
}
private int newPareto;
public int NewPareto
{
get
{
return newPareto;
}
set
{
if (newPareto == value)
return;
newPareto = value;
OnPropertyChanged("NewPareto");
OnPropertyChanged("pNew");
}
}
public bool pNew
{
get
{
return CurrentPareto < NewPareto;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Edit
编辑
To simplify it a little, you could use a base ViewModel class and use PropertyChanged
weaving. The code would simplify to this:
为了稍微简化它,您可以使用基础 ViewModel 类并使用PropertyChanged
编织。代码将简化为:
public class FooViewModel : ViewModelBase
{
public int CurrentPareto { get; set; }
public int NewPareto { get; set; }
public bool pNew { get { return CurrentPareto < NewPareto; } }
}
回答by ChibaKun
Why can't you just use this property to get the number of rows and then use a For loop to iterate through?
为什么不能只使用此属性来获取行数,然后使用 For 循环进行迭代?
dataGridView1.Rows.Count
回答by Charles Clayton
People seem to be overcomplicating this, this worked for me:
人们似乎对此过于复杂,这对我有用:
foreach (System.Data.DataRowView dr in yourDataGrid.ItemsSource)
{
MessageBox.Show(dr[0].ToString());
}
回答by Francis Altura Japson
I don't even understand why is it just so complicated to get rows and their values in a datagrid. It feels like hell finding how. The api even give funny funny event names which is not so direct to the point also. Why can't just people concentrate on the baseline and give what exactly is needed and not all sorts of different options with no use and sense at all. I mean to eat all you need is a spoon and fork right. Never even changed since 100,000 years ago. This is my code thanks to the guy who mentioned some people just try to over-complicate things and waste your time.
我什至不明白为什么在数据网格中获取行及其值如此复杂。找到方法的感觉就像地狱。api 甚至给出了有趣的事件名称,这也不是那么直接。为什么不能只是人们专注于基线并给出确切需要的东西,而不是各种毫无用处和意义的不同选项。我的意思是吃你所需要的只是一个勺子和叉子。自 100,000 年前以来甚至从未改变过。这是我的代码,感谢提到有些人只是试图使事情过于复杂并浪费您的时间的人。
private void dtaResultGrid_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ActivateTestDatagridAccess();
}
public async void ActivateTestDatagridAccess()
{
try
{
await Task.Delay(500);
foreach (System.Data.DataRowView dr in dtaResultGrid.ItemsSource)
{
for (int j = 0; j < dtaResultGrid.Columns.Count; j++)
{
Console.WriteLine(dr[j].ToString());
}
Console.Write(Environment.NewLine);
}
}
catch (Exception exrr)
{
Console.WriteLine(exrr.ToString());
}
}
回答by StudioX
if you fill your datagridview rows using an instance of a class (like struct_class) this would be the fastest way to have a foreach loop
如果您使用类的实例(如 struct_class)填充 datagridview 行,这将是使用 foreach 循环的最快方法
foreach (struct_class row in dgv.Items)
{
MessageBox.Show(row.name);
}