以编程方式为DataGrid创建WPF DataGridTemplateColumn

时间:2022-09-10 21:02:50

I would like to be able to programmatically create DataGridTemplateColumns based on my data source. For example, if my source has a date in a particular column I would like to be able to utilize a Datepicker control. I know this is easily accomplished with xaml and a DataGridTemplateColumn at design-time, however, how would I accomplish this at run-time?

我希望能够以编程方式基于我的数据源创建DataGridTemplateColumns。例如,如果我的源在特定列中有日期,我希望能够使用Datepicker控件。我知道在设计时可以使用xaml和DataGridTemplateColumn轻松完成,但是,如何在运行时完成此操作?

Is my best option xamlreader.load or a more traditional route like:

是我最好的选择xamlreader.load或更传统的路线,如:

Dim TempCol As Microsoft.Windows.Controls.DataGridTemplateColumn

Dim TempCol As Microsoft.Windows.Controls.DataGridTemplateColumn

I have not had any success with the latter.

我对后者没有任何成功。

Thanks.

-Paul

Edit: This is the code I attempted to use:

编辑:这是我尝试使用的代码:

        Dim TempCol As New Microsoft.Windows.Controls.DataGridTemplateColumn

    TempCol.CellEditingTemplate = DataTemplate.Equals(DatePicker)

I receive DatePicker is a type and cannot be used as an expression.

我收到DatePicker是一个类型,不能用作表达式。

I am basiing this on the WPF Toolkit demo. http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-datagrid-feature-walkthrough.aspx

我在WPF工具包演示中基于此。 http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-datagrid-feature-walkthrough.aspx

<dg:DataGridTemplateColumn Header="Date" MinWidth="100">
    <dg:DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <dg:DatePicker SelectedDate="{Binding Date}" SelectedDateFormat="Short" />
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellEditingTemplate>
    <dg:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Date, StringFormat=d}" />
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>

Thanks!

1 个解决方案

#1


The reason that your code does not work is because you are setting the value of the CellEditingTemplate column to a bool (the result of calling DataTemplate.Equals(), rather than creating an instance of the template in code.

您的代码不起作用的原因是您将CellEditingTemplate列的值设置为bool(调用DataTemplate.Equals()的结果,而不是在代码中创建模板的实例。

You can create a template in code using something like this (equivalent to the XAML code snippet you provided):

您可以使用类似的东西在代码中创建模板(相当于您提供的XAML代码段):

DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = "Date";

// Create a factory. This will create the controls in each cell of this
// column as needed.
FrameworkElementFactory factory =
    new FrameworkElementFactory(typeof(DatePicker));

// Bind the value of this cell to the value of the Date property of the
// DataContext of this row. The StringFormat "d" will be used to display
// the value.
Binding b = new Binding("Date");
b.StringFormat = "d";
factory.SetValue(DatePicker.SelectedDateProperty, b);

// Create the template itself, and add the factory to it.
DataTemplate cellEditingTemplate = new DataTemplate();
cellEditingTemplate.VisualTree = factory;

col.CellEditingTemplate = cellEditingTemplate;

I'm not sure if this approach would work better than loading the XAML yourself. Maybe try both approaches and see which one works best for you, and works faster?

我不确定这种方法是否比自己加载XAML更好。也许尝试两种方法,看看哪种方法最适合你,并且工作得更快?

#1


The reason that your code does not work is because you are setting the value of the CellEditingTemplate column to a bool (the result of calling DataTemplate.Equals(), rather than creating an instance of the template in code.

您的代码不起作用的原因是您将CellEditingTemplate列的值设置为bool(调用DataTemplate.Equals()的结果,而不是在代码中创建模板的实例。

You can create a template in code using something like this (equivalent to the XAML code snippet you provided):

您可以使用类似的东西在代码中创建模板(相当于您提供的XAML代码段):

DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = "Date";

// Create a factory. This will create the controls in each cell of this
// column as needed.
FrameworkElementFactory factory =
    new FrameworkElementFactory(typeof(DatePicker));

// Bind the value of this cell to the value of the Date property of the
// DataContext of this row. The StringFormat "d" will be used to display
// the value.
Binding b = new Binding("Date");
b.StringFormat = "d";
factory.SetValue(DatePicker.SelectedDateProperty, b);

// Create the template itself, and add the factory to it.
DataTemplate cellEditingTemplate = new DataTemplate();
cellEditingTemplate.VisualTree = factory;

col.CellEditingTemplate = cellEditingTemplate;

I'm not sure if this approach would work better than loading the XAML yourself. Maybe try both approaches and see which one works best for you, and works faster?

我不确定这种方法是否比自己加载XAML更好。也许尝试两种方法,看看哪种方法最适合你,并且工作得更快?