C# 将DataTemplate绑定到DataGridColumn CellTemplate

C# 将DataTemplate绑定到DataGridColumn CellTemplate,c#,wpf,binding,datatemplate,datagridcolumn,C#,Wpf,Binding,Datatemplate,Datagridcolumn,我正在尝试在代码中设置DatePicker DataGrid列。此列用于不同的数据网格,每个数据网格显示不同类型的对象。从那时起,我想出了以下代码,它工作正常: public DataGridColumn GetDataGridColumn(string header, bool isReadOnly, string fieldName) { DataGridTemplateColumn dgCol = new DataGridTemplateColumn(); dgCol.He

我正在尝试在代码中设置DatePicker DataGrid列。此列用于不同的数据网格,每个数据网格显示不同类型的对象。从那时起,我想出了以下代码,它工作正常:

public DataGridColumn GetDataGridColumn(string header, bool isReadOnly, string fieldName)
{
    DataGridTemplateColumn dgCol = new DataGridTemplateColumn();
    dgCol.Header = header;
    dgCol.IsReadOnly = isReadOnly;

    FrameworkElementFactory dateFactory = new FrameworkElementFactory(typeof(DatePicker));
    dateFactory.SetBinding(DatePicker.SelectedDateProperty, new Binding(fieldName));
    dateFactory.SetValue(DatePicker.IsEnabledProperty, !isReadOnly);

    DataTemplate cellTemplate = new DataTemplate();
    cellTemplate.VisualTree = dateFactory;

    dgCol.CellTemplate = cellTemplate;

    return dgCol;
}
然而,既然
FrameworkElementFactory
是,我想我最好寻找另一种方法

作为替代方案,我考虑创建一组数据模板作为资源,然后在代码中应用它们。到目前为止,我已经做到了这一点,但我不确定如何设置绑定。这是我的日期选择器模板:

<DataTemplate x:Key="DatePickerColumnCellTemplate">
    <DatePicker SelectedDate="{Binding Path=StartDate}" />
</DataTemplate>
这种新方法似乎是一种更优雅的解决方案,因为现在DatePicker列的UI设计是用XAML定义的,并且只使用代码应用。但是,现在我的DatePicker列只显示开始日期。方法中的
fieldName
参数可以是“StartDate”或“EndDate”或在数据网格中显示的对象中定义的任何其他日期时间变量。另外,我不知道如何将DatePicker
IsEnabled
属性设置为isReadOnly的值

如果你认为这不是最好的方法,那么请让我知道


谢谢。

因为还没有答案,所以我想出了一个解决办法

我没有找到一种方法来连接在XAML中创建的模板的绑定,而是开始研究我要做的事情——创建一个DatePicker DataGridColumn。因此,我通过继承数据网格列的抽象基类创建了自己的
DatePickerDataGridColumn
类:

public class DatePickerDataGridColumn : DataGridColumn
{
    public DatePickerDataGridColumn() : base() { }

    public BindingBase SelectedDateBinding { get { return _selectedDateBinding; } set { _selectedDateBinding = value; } }
    private BindingBase _selectedDateBinding = null;

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) { return null; }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        DatePicker picker = new DatePicker();
        picker.IsEnabled = !IsReadOnly;
        picker.BorderThickness = new Thickness(0.0);

        if (SelectedDateBinding != null)
        {
            picker.SetBinding(DatePicker.SelectedDateProperty, SelectedDateBinding);
        }

        return picker;
    }
}
然后,我的GetDataGridColumn方法变成:

public override DataGridColumn GetDataGridColumn(string header, bool isReadOnly, string fieldName)
{
    DatePickerDataGridColumn dgCol = new DatePickerDataGridColumn();
    dgCol.Header = header;
    dgCol.IsReadOnly = isReadOnly;

    Binding b = new Binding(fieldName);
    if (isReadOnly) { b.Mode = BindingMode.OneWay; }
    dgCol.SelectedDateBinding = b;

    return dgCol;
}
public override DataGridColumn GetDataGridColumn(string header, bool isReadOnly, string fieldName)
{
    DatePickerDataGridColumn dgCol = new DatePickerDataGridColumn();
    dgCol.Header = header;
    dgCol.IsReadOnly = isReadOnly;

    Binding b = new Binding(fieldName);
    if (isReadOnly) { b.Mode = BindingMode.OneWay; }
    dgCol.SelectedDateBinding = b;

    return dgCol;
}