WPF итерации через datagrid

С использованием WPF и C#.Серии net4.5 с помощью Visual студии ульта 2012.

старый код 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
       }
}

как вы можете видеть, каждая строка я цикл через Я проверить определенную ячейку, если true я затем заполнить другую ячейку. Это был старый добрый код winforms, который я использовал много раз раньше...однако. Переключение на WPF было намного больше, чем я предполагал ранее.

DataGrid не содержит Row собственность. Вместо этого, я думаю, вам нужно использовать:

DataGridRow paretoRow in paretogrid.Items

но я все еще в недоумении, кто теперь получит сотовый.

Итак, мой вопрос, есть ли изменения синтаксиса для выполнения, если да, то где? Или, как я начинаю верить, datagrids в WPF работают с объектами больше, чем winforms, поэтому не нужно использовать свойство под названием "row", если это так, какую логику/синтаксис я должен знать в этом примере?

Спасибо за ваше терпение, ребята, думаю, когда я вернусь домой на банковские каникулы, я сделаю немного WPF копать, чтобы увидеть, насколько все на самом деле.

5 ответов


Я думаю, что сначала думаю, что вы хотите сделать, это получить все строки вашего 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 (System.Data.DataRowView dr in yourDataGrid.ItemsSource)
{
     MessageBox.Show(dr[0].ToString());
}

в WPF вы идете об этом намного более динамично и ObjectOrientated. Вы можете привязать столбец "pNew" к свойству элемента, который вы помещаете в DataGrid, который возвращает downarrow. При изменении значения можно вызвать событие PropertyChanged (интерфейс INotifyPropertyChanged) и свойство bound будет переоценено.

также интересно для начала с WPF является DataTemplate, ControlTemplate, Converter. Преобразователь изменяет значение свойства на полезное значение для WPF (например, BoolToVisibility), когда свойство вызывается. DataTemplate и ControlTemplate может использоваться для изменения внешнего вида элемента управления.

есть несколько хороших учебников для WPF. Я бы также рекомендовал изучить шаблон MVVM для использования в качестве промежуточного уровня вашего Businessobject и вашего WPF-Control, особенно для обработки таких вещей, как то, что вы пытаетесь сделать здесь.


Да, вы правы. В WPF DataGrid построен вокруг лучшей поддержки использования объектов.

вы можете использовать ViewModel, похожий на следующий. Создайте их все в коллекцию, а затем установите эту коллекцию в качестве ItemsSource. Вам также нужно будет использовать ValueConverter, если вы хотите отобразить и изображение вместо флажка pNew, являющегося true / false.

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

почему вы не можете просто использовать это свойство, чтобы получить количество строк, а затем использовать цикл for для перебора?

dataGridView1.Rows.Count