Простая привязка данных к DataGrid (WPF) из ObservableCollection? - PullRequest
0 голосов
/ 17 октября 2011

У меня есть «ObservableCollection», в которой хранятся отформатированные метки ColumnLabels, которые необходимо вставить в DataGrid.

Коллекция может иметь множество различных записей и может иметь размер 'N', поэтому в моей DataGrid будет столбец 'N'. Определено ниже:

    private ObservableCollection<string> _stockColumnLabels;
    public ObservableCollection<string> StockColumnLabels 
    {
        get 
        {
            if (_stockColumnLabels == null)
            {
                _stockColumnLabels = new ObservableCollection<string>();
                return _stockColumnLabels;
            }
            return _stockColumnLabels; 
        }
        set
        {
            _stockColumnLabels = value;
            //OnPropertyChanged("StockColumnLabels");
        } 
    }

Пример данных, которые будут храниться в этой коллекции, например:

  1. "1"
  2. "2"
  3. "3"
  4. "4"
  5. "5"

N.B, все строки, конечно, по сути, можно рассматривать как одну строку данных, которые представляют столбцы при просмотре в графическом интерфейсе.

Коллекция превращается в свойство для DataBinding и живет в ViewModel, а DataGrid живет в View. DataContext для представления устанавливается в RunTime при запуске файла App.cs!

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        MainWindow window = new MainWindow();
        window.DataContext = new FSEnquiryViewModel();
        window.Show();
    }
}

GUI (ПРОСМОТР)

В настоящее время из-за характера требований, устанавливаемых для этого проекта, имена столбцов должны быть отформатированы вне ProductCode, чтобы облегчить жизнь, я создал одну DataGrid, которая просто содержит одну строку данных, которые являются именами столбцов а затем еще один DataGrid чуть ниже, который будет содержать значения строк. Не беспокойтесь о втором DataGrid, я расскажу об этом позже, так как настройка точно такая же. На данный момент кто-то может помочь мне «Привязать» мою коллекцию ObservableCollection, найденную в моей ViewModel, к моей DataGrid, это всего лишь одна полоса данных.

Чтобы выглядеть как

           1         2         ...       n         <- 'DataGrid1'
Row1 |     1    |    3    |    5    |    6    |    <- 'DataGrid2'
Row2 |     3    |    2    |    1    |    8    |

Ответы [ 3 ]

1 голос
/ 24 октября 2011

Мой код ниже надеется ответить на вопрос, который позволяет связывать данные из неизвестного количества источников, каждый результат может быть неизвестного размера, а также потенциальное количество столбцов, которые могут быть использованы.Затем медленно формируйте результаты построчно в динамическую коллекцию, которая представляет окончательный макет данных.

По сути, примерно так же, как в ответе BlindMeis, но он разместил код, который был некорректно синтаксически и не выглядел так, как будтобыл проверен перед публикацией.Ниже приведен мой код, который я сейчас использую.

Ниже вы найдете то, что сработало для меня, если у вас есть набор результатов или наборы для начала.

  1. Объявитьтаблица для хранения ваших результатов.

    DataTable shapeResultsTable = new DataTable ();

  2. Следующим шагом будет фильтрация некоторых результатов из вызова БД или процедуры, которая приводитВы пытаетесь изменить форму.Что-то вроде:

        foreach (DataRow row in whFreeResults.Rows)
        {
            // filter your results and strip exactly the data you need to represent your column names.
            // dump your results into a sample list e.g: 'columnNamesFormatted'
    
        }
    
  3. Как только у вас будет список имен столбцов, добавьте их в свою таблицу данных, объявленную выше.

        foreach (string column in columnNamesFormatted)
        {
            shapedResultsTable.Columns.Add(column, typeof(string));
        }
    
  4. Затем объявите, создайте экземпляр и заполните список неизвестного размера, потому что ваши результаты имеют размер n или количество n, чтобы сохранить значения строк.

  5. Затем повторите шаги 2 и 3 для каждой строки данных, которую вы хотите отобразить в новой таблице данных с сформированными результатами, более одного для каждой строки, найденной в наборе результатов.

  6. Когда у вас есть несколько коллекций, представляющих каждую строку, которую вы хотите добавить в таблицу данных.Добавьте их в том порядке, в котором вы хотите, чтобы они отображались.

    shapeResultsTable.Rows.Add (totalsArray.ToArray ());shapeResultsTable.Rows.Add (branchRowValues.ToArray ());

  7. Наконец, присвойте свой DataTable «свойству DataBinded».

    StockResultsTable = shapeResultsTable;

  8. Связанное свойство может выглядеть следующим образом:

    private DataTable _stockResultsTable;
    public DataTable StockResultsTable
    {
        get { return _stockResultsTable; }
        set 
        { 
            _stockResultsTable = value;
            OnPropertyChanged("StockResultsTable"); // <--- defo' need this one.
        }
    }
    
  9. Наконец, xaml на переднем конце может выглядеть следующим образом:

            <DataGrid Height="179" 
              HorizontalAlignment="Left" 
              Margin="151,0,0,211" 
              Name="dgStockInfo" 
              VerticalAlignment="Bottom" 
              Width="393" 
              ItemsSource="{Binding Path = StockResultsTable}" AutoGenerateColumns="True" Padding="0,10" FontSize="14" />
    

Я не знаю, почему свойство автогенерации столбцов включено, но это работает для меня.

Шаги 1-9 работал для меня, работая с образцом набора данных результатов, возвращаемых запросом или SProc. Приведенные выше шаги кратко описывают то, что я делал при отображении результатов многочисленных запросов, которые мне нужно было выполнить, чтобы получить совершенно разные данные из множества различных SProcs, ноУ них была общая базовая тема, которая позволяла отображать их под общими именами столбцов.

Помните о том, что у вас возникнут проблемы при добавлении строки данных, в которой больше элементов, чемТаблица данныхимеет столбцы.DT, который имеет 6 столбцов, но вы добавляете строку, которая была получена из другого запроса, которая имеет 7 отдельных ячеек данных.Это не сработает, просто добавьте новый столбец, которого еще нет, и попробуйте снова.

0 голосов
/ 19 октября 2011

Является ли ваша коллекция заголовков столбцов того же размера, что и коллекция "data"?Если это так, вы можете сделать это после InializeComponent ().(Примечание: это может нарушить некоторые правила MVVM, но это зависит от того, насколько строго вы хотите следовать)

        InitializeComponent();
        DataContext = vm;
        dataGrid1.ItemsSource = vm.DgData; // this can also be done via XML binding
        dataGrid1.AutoGenerateColumns = true;
        foreach (var column in dataGrid1.Columns)
        {
            column.Header = vm.ColumnHeaders[column.DisplayIndex];
        }     
0 голосов
/ 17 октября 2011

РЕДАКТИРОВАТЬ: DataTable работает отлично. Просто используйте ViewTable, чтобы собрать свою коллекцию, готовую для просмотра. я предполагаю, что размер вашей коллекции заголовков совпадает с размером данных.

this.dt = new DataTable();

dt.Columns.Add(new Column("1")); //1..n columns
dt.Columns.Add(new Column("n"));

затем введите ваши данные для ранее определенных столбцов и столько строк данных, сколько у вас есть

var newrow = dt.NewRow();
newrow[0] = "value1"; //0..n-1 columns
dt.AddRow(newrow);

viewmodel property

publlic DataTable MyDynamicDataTable {get{return this.dt;}}

переплет в xaml

 <DataGrid ItemsSource="{Binding MyDynamicDataTable}" AutogenerateColumns="true" />

вам не нужно ничего делать в вашей сетке данных представления, вся информация поступает из модели представления.

...