好问题,我会使用ContentControl
,代码仍然会有点膨胀,但它比复制整个模板要好,例如:
<DataGrid ItemsSource="{Binding EmpSets}">
<DataGrid.Resources>
<DataTemplate DataType="{x:Type obj:Employee}">
<TextBlock>
<Run Text="{Binding Name}"/>
<Run Name="RunChan" Text=" - "/>
<Run Text="{Binding Occupation}"/>
</TextBlock>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Emp1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Emp1}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Emp2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Emp2}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- ... -->
</DataGrid.Columns>
</DataGrid>
在这里,我在资源中使用一个隐式 DataTemplate,但您也可以将其显式应用为ContentTemplate
通过定义和引用一个键来控制每个 ContentControl,但无论如何你都知道这一点。
准系统子类化方法:
public class DataGridTemplateMemberColumn : DataGridTemplateColumn
{
public static readonly DependencyProperty MemberPathProperty =
DependencyProperty.Register("MemberPath", typeof(string), typeof(DataGridTemplateMemberColumn), new UIPropertyMetadata(null));
public string MemberPath
{
get { return (string)GetValue(MemberPathProperty); }
set { SetValue(MemberPathProperty, value); }
}
protected override System.Windows.FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
return GenerateContent(CellEditingTemplate, dataItem);
}
protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
return GenerateContent(CellTemplate, dataItem);
}
private FrameworkElement GenerateContent(DataTemplate template, object dataItem)
{
var contentControl = new ContentControl();
contentControl.ContentTemplate = template;
if (MemberPath != null)
{
Binding binding = new Binding(MemberPath);
binding.Source = dataItem;
contentControl.SetBinding(ContentControl.ContentProperty, binding);
}
else
{
contentControl.Content = dataItem;
}
return contentControl;
}
}
<DataGrid.Columns>
<cex:DataGridTemplateMemberColumn MemberPath="Emp1" />
<cex:DataGridTemplateMemberColumn MemberPath="Emp2" />
<cex:DataGridTemplateMemberColumn MemberPath="Emp3" />
<cex:DataGridTemplateMemberColumn MemberPath="Emp4" />
<cex:DataGridTemplateMemberColumn MemberPath="Emp5" />
</DataGrid.Columns>