16

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

4

7 回答 7

28

我认为首先你想做的是得到你的所有行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);
      }
  } 
于 2013-03-28T16:19:13.033 回答
28

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

foreach (System.Data.DataRowView dr in yourDataGrid.ItemsSource)
{
     MessageBox.Show(dr[0].ToString());
}
于 2015-01-13T23:42:44.623 回答
1

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

您可以使用类似于以下内容的 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; } }
}
于 2013-03-28T16:35:53.190 回答
1

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

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

从 WPF 开始也很有趣的是DataTemplate, ControlTemplate, Converter. 当调用属性时,转换器将属性值更改为 WPF 的可用值(例如 BoolToVisibility)。 DataTemplate并可ControlTemplate用于更改控件的外观。

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

于 2013-03-28T16:21:25.560 回答
0

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

foreach (struct_class row in dgv.Items)
{
    MessageBox.Show(row.name);
}
于 2019-09-17T08:12:59.100 回答
-4

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

dataGridView1.Rows.Count
于 2014-12-28T08:42:09.480 回答