【问题标题】:WPF iterate through datagridWPF 遍历数据网格
【发布时间】:2013-03-19 03:49:11
【问题描述】:

使用 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 中的数据网格比 winforms 更多地使用对象操作,因此不需要使用称为“行”的属性,如果是这种情况,我应该知道在这个例子中使用什么逻辑/语法?

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

【问题讨论】:

标签: c# wpf datagrid


【解决方案1】:

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

【讨论】:

  • 那么我如何获取所有行?查看我的 foreach 循环,我曾经使用 datgridviewrow hwoever,但它不适用于 WPF,你将如何获得所有行?
  • 感谢您提供的代码,请试一试。与winforms相比,起初它看起来仍然很冗长,一个简单的3 liner变得更加复杂。但我想这是对我当前方法的修复,这应该是改变。我这样想对吗?
  • 在 var itemsource = grid.itemsource 下获得了一个语法红色内衬作为 ienumerable。错误是别名“IEnumerable”说“需要 1 种类型的争论”
  • “你需要确保你的网格中有itemsource”你是什么意思?请耐心等待我大声笑
  • 非常有用,但自 2009 年 3 月发布的 silverlight 工具包将命名空间 microsoft.windows.controls 更改为 system.windows.controls :silverlight.codeplex.com/… 代码将稍作更改,您需要有:使用 System.Collections.Generic;使用 System.Collections;修复“IEnumerable”的错误,说“需要一种类型的争论”
【解决方案2】:

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

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

【讨论】:

  • 我认为人们喜欢让事情变得比他们必须的更复杂。
  • 我建议使用 yourDataGrid.Items 而不是 yourDataGrid.ItemsSource。这将根据已排序的列维护任何用户应用的排序方向。
  • 不工作,它显示错误无法将对象转换为 System.Data.DataRowView
  • 这对我来说是一个奇迹。在某个地方应该有一个网站,它只是针对常见问题的 KISS 解决方案......比如“最小代码解决方案”
【解决方案3】:

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

您可以使用类似于以下内容的 ViewModel。将它们全部构建到一个集合中,然后将该集合设置为您的ItemsSource。如果要显示和图像,而不是 pNew 为真/假的复选标记,您还需要使用 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; } }
}

【讨论】:

    【解决方案4】:

    我什至不明白为什么在数据网格中获取行及其值如此复杂。感觉就像地狱一样。该 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());
            }
        }
    

    【讨论】:

      【解决方案5】:

      在 WPF 中,您可以更加动态和面向对象。您可以将列“pNew”绑定到您放在DataGrid 中的元素的属性上,这将返回向下箭头。 如果值发生变化,您可以引发事件PropertyChanged(接口INotifyPropertyChanged)并且绑定的属性将被重新评估。

      从 WPF 开始的还有 DataTemplateControlTemplateConverter。 当调用属性时,转换器将属性值更改为 WPF 的可用值(例如 BoolToVisibility)。 DataTemplateControlTemplate 可用于更改控件的外观。

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

      【讨论】:

      • 感谢您的建议,这绝对是我本周末正在研究的事情。目前我正在寻找这种解决方案的一种“破解”,只是想看看你如何使用winforms风格的方法来做到这一点。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        dataGridView1.Rows.Count
        

        【讨论】:

        • 你的答案是正确的(所以我给了它一个赞成票)。也许大多数反对者可能想要更多示例代码? (我希望投票需要评论。)
        • 此答案不正确,因为 WPF DataGrid 没有名为 Rows 的成员。这实际上在这个线程中之前提到过。但我也希望投票需要评论。
        猜你喜欢
        • 1970-01-01
        • 2023-03-20
        • 2013-05-27
        • 2011-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-24
        相关资源
        最近更新 更多