如何在DataGrid控件中包含ListBox

时间:2016-01-21 11:47:44

标签: c# wpf xaml datagrid listbox

我正在使用MVVM模式开发WPF 4应用程序。我有一个DataGrid控件,其中列自动生成并与DataTable对象绑定。

我的表现在是这样的:

+------------+---------------+---------------+
| Date       | Shop 1        | Shop 2        |
+------------+---------------+---------------+
| 2016-01-01 | 09:00 - 13:00 | N/A           |
+------------+---------------+---------------+
| 2016-01-02 | N/A           | 14:00 - 18:00 |
+------------+---------------+---------------+

我需要这个结果:

+------------+---------------+---------------+
| Date       | Shop 1        | Shop 2        |
+------------+---------------+---------------+
| 2016-01-01 | 9:00 - 13:00  | N/A           |
|            | 14:00 - 18:00 |               |
+------------+---------------+---------------+
| 2016-01-02 |               | 14:00 - 18:00 |
|            | 9:00 - 10:00  |               |
|            | 12:00 - 14:00 |               |
+------------+---------------+---------------+

对于每个小时范围,我需要不同的颜色,所以我会为表格的每个单元格绑定一个列表框。

实际上我的XAML代码是这样的:

<DataGrid x:Name="grdScheduler" 
          IsEnabled="False"
          AutoGenerateColumns="True" 
          HeadersVisibility="None" 
          ItemsSource="{Binding SchedulerDataTable, Mode=OneWay}">            
</DataGrid>

拜托,你能帮助我吗?

由于

1 个答案:

答案 0 :(得分:0)

我认为this与你所问的类似。但我做了一个适合你问题的例子。

您需要为DataGridtemplateColumn列类型提供List<object>。为此,我们为Datagrid的AutoGeneratingColumn事件创建一个事件处理程序。是的,您需要编写一些代码,但这不会破坏MVVM世界中的任何内容。您可以编写代码,或者如果您想要更清晰的方法,可以实现自己的数据网格自定义控件。 现在在DataGrid.Resource中,我们有一个名为ListTemplate的DataTemplate。这将是每个List<object>列的单元格模板。

<DataGrid x:Name="grdScheduler" 
      IsEnabled="False"
      AutoGenerateColumns="True" 
      HeadersVisibility="None" 
      ItemsSource="{Binding SchedulerDataTable, Mode=OneWay}"         
      AutoGeneratingColumn="grdScheduler_AutoGeneratingColumn">
  <DataGrid.Resources>
    <DataTemplate x:Key="ListTemplate">
      <ListBox ItemsSource="{Binding}" />
    </DataTemplate>
  </DataGrid.Resources>
</DataGrid>

对于List<object>类型的每一列,您需要使用DynamicDataGridTemplateColumn并使用 ListTemplate 作为CellTemplate。在此代码块中,您还可以根据需要为每个生成的列使用不同的模板。

    private void grdScheduler_AutoGeneratingColumn(object sender, System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs e)
    {
      if (e.PropertyType == typeof(List<object>))
      {
        DynamicDataGridTemplateColumn dgTemplateCol = new DynamicDataGridTemplateColumn();
        dgTemplateCol.CellTemplate = (sender as DataGrid).FindResource("ListTemplate") as DataTemplate;
        dgTemplateCol.ColumnName = e.PropertyName;
        e.Column = dgTemplateCol;
      }
    }

这是DynamicDataGridTemplateColumn的代码。

  public class DynamicDataGridTemplateColumn : DataGridTemplateColumn
  {
    public string ColumnName
    {
      get;
      set;
    }

    protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
      // The DataGridTemplateColumn uses ContentPresenter with your DataTemplate.
      ContentPresenter cp = (ContentPresenter)base.GenerateElement(cell, dataItem);
      // Reset the Binding to the specific column. The default binding is to the DataRowView.
      BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName));
      return cp;
    }
  }