WPF迭代数据网格

使用Visual Studio 2012 ulti使用WPF C#.NET4.5。

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

你可以看到我循环的每一行我检查一个特定的单元格,如果是,我然后填充另一个单元格。 这是我以前用过很多次的好的winforms代码……但是。 切换到WPF与我之前假设的有很多不同。

DataGrid不包含Row属性。 相反,我认为你需要使用:

 DataGridRow paretoRow in paretogrid.Items 

但我现在仍然不知道谁将获得这个细胞。

所以我的问题是,是否有语法更改要执行,如果是这样的话? 或者我开始相信WPF中的数据网格比使用对象更多,因此不需要使用称为“行”的属性,如果是这种情况,我应该知道在这个例子中应该使用什么逻辑/语法?

感谢您的耐心等待,想想当我回家度假时,我会做一些WPF挖掘,看看它实际上有多么不同。

我想首先想你要做的是获取你的DataGrid所有行:

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

然后遍历你的网格:

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

人们似乎过于复杂,这对我有用:

 foreach (System.Data.DataRowView dr in yourDataGrid.ItemsSource) { MessageBox.Show(dr[0].ToString()); } 

在WPF中,你会更加动态和ObjectOrientated。 您可以将列“pNew”绑定到放在DataGrid中的元素的Property上,该元素将返回downarrow。 如果值更改,则可以引发Event PropertyChanged (接口INotifyPropertyChanged ),并且将重新评估绑定的Property。

从WPF开始也很有趣的是DataTemplateControlTemplateConverter 。 当调用Property时,Converter将属性值更改为WPF的可用值(例如BoolToVisibility)。 DataTemplateControlTemplate可用于更改Control的外观。

WPF有几个很好的教程。 我还建议调查MVVM-Pattern以用作Businessobject和WPF-Control的层之间,尤其是处理您尝试在此处执行的操作。

是的,你是对的。 WPF DataGrid是围绕更好地支持对象的使用而构建的。

您可以使用类似于以下的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)); } } } 

编辑

为了简化它,您可以使用基本的ViewModel类并使用PropertyChanged编织。 代码将简化为:

 public class FooViewModel : ViewModelBase { public int CurrentPareto { get; set; } public int NewPareto { get; set; } public bool pNew { get { return CurrentPareto < NewPareto; } } } 

我甚至不明白为什么在数据网格中获取行及其值这么复杂。 感觉好像在寻找怎么样。 api甚至给出了有趣的有趣事件名称,这也不是那么直接。 为什么不能只是人们专注于基线并提供所需的东西而不是所有种类的不同选择,根本没有用处和意义。 我的意思是吃所有你需要的是一把勺子和叉子吧。 自从10万年前以来从未改变过。 这是我的代码,感谢那些提到有些人试图过度复杂化并浪费你的时间的人。

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

为什么不能只使用此属性来获取行数,然后使用For循环来迭代?

 dataGridView1.Rows.Count