WPF迭代数据网格

时间:2013-03-28 15:52:04

标签: c# wpf datagrid

使用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挖掘,看看它实际上有多么不同。

7 个答案:

答案 0 :(得分:20)

我认为您首先想要做的是获取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;
    }
}

然后遍历你的网格:

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

答案 1 :(得分:19)

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

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

答案 2 :(得分:1)

是的,你是对的。 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; } }
}

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

我什至不明白为什么在数据网格中获取行及其值如此复杂。感觉如何找到方法。该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());
        }
    }

答案 5 :(得分:0)

如果您使用类的实例(例如struct_class)填充datagridview行 这将是有一个foreach循环的最快方法

foreach (struct_class row in dgv.Items)
{
    MessageBox.Show(row.name);
}

答案 6 :(得分:-4)

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

dataGridView1.Rows.Count