none
Привязки в DataGridTemplateColumn RRS feed

  • Вопрос

  • Здравствуйте. Я новичек в WPF и никак не могу сообразить, как сделать привязку данных для такого случая.

    Требуется разработать приложения для составления графика работы персонала. График вывожу через DataGrid, для которого 2 колонки фиксированы (Ф, И. О. и таб. номер), а остальные колонки генерируются в зависимости от числа дней в заданном месяце.

    DataGrid привязывается к DataTable, который имеет колонки Name (string), Code (int) и колонку для каждого месяца ("d1", "d2", "d3" и т. д.) (к слову, схема DataGrid генерируется программно, а не из таблицы БД).

    Данные, хранящиеся в колонке дней представлены классом Day:

    class Day {
    	public int Hours { get; set; }	// время работы
    	public int Shift { get; set; } 	// смена 
    }
    

    Так создается DataTable:

    var dt = new DataTable();
    dt.Columns.Add("Name", typeof(string));
    dt.Columns.Add("Code", typeof(int));
    int ndays = DateTime.DaysInMonth(year, month);
    for (int i = 1; i <= ndays; i++)
    {
     dt.Columns.Add("d" + i.ToString(), typeof(Day));
    }
    
    И после заполнения привязывается к гриду через свойство ItemsSource.

    Помогите, пожалуйста, составить шаблон данных для ячеек DataGrid'а. Если первые две колонки простые DataGridTextColumn, то для отображения дней необходимы DataGridTemplateColumn'ы. Как сделать привязки в ячейке, отностительно объекта Day, примерно следующим образом:

    <DataTemplate>
    	<Grid Height="30" Width="32">
    		<Label Content="{Binding Path=Hours}" HorizontalAlignment="Left" VerticalAlignment="Top" Padding="1" />
    		<Label Content="{Binding Path=Shift}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Padding="1" />
    	</Grid>
    </DataTemplate>
    

    Я еще не достаточно хорошо знаком с WPF и буду рад за любую помощь.


    • Изменено Nogrik 29 июля 2011 г. 9:31 Ошибка в коде
    29 июля 2011 г. 9:29

Ответы

  • Если колонок для месяцев у нас всегда 12, то для каждого месяца надо делать колонку:
      <DataGrid x:Name="grid">
       <DataGrid.Columns>
        <DataGridTemplateColumn>
         <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
           <Label Content="{Binding d1.Day}"/>
          </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
       </DataGrid.Columns>
      </DataGrid>
    
    Если же колонки создаются в момент работы, то все несколько хитрее, в контроле надо динамически добавлять колонки в грид руководствуясь схемой или что там есть ещё. Колонку же надо сделать свою унаследованную от DataGridTemplateColumn, примерный код:
     public class MonthDataColumn : DataGridTemplateColumn
     {
      public string Month;
    
      protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
      {
       // Заставляем сгенерировать элемент базовый код
       var element = base.GenerateEditingElement(cell, dataItem);
       // dataItem это экземпляр строки из DataTable
       var row = dataItem as RowItem;
       // По заданному месяцу получаем непосредственно данные
       var dayData = row[Month];
       // Цепляем данные сгенерированному элементу
       element.DataContext = dayData;
      }
     }
    

    Названия классов и т.п. только для общего представления что надо сделать. При создании колонки, в Month задаем месяц, например строки "d1", "d2", а далее уже по идентификатору месяца получаем данные за месяц из строки. Или же можно задавать делегат Func<RowItem, Day> для получения данных. В этом ключе в общем надо копать.

    http://gvozdin.ru
    • Помечено в качестве ответа Abolmasov Dmitry 1 августа 2011 г. 8:49
    30 июля 2011 г. 15:21