在WPF数据网格中,我有一个定义为DataGridTemplateColumn的列,我需要在各种列上使用它。作为一个非常简单的示例,请将以下内容视为虚拟样本:
<DataGrid ItemsSource="{Binding Path=ItemList, Mode=OneWay}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name" MinWidth="130" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel LastChildFill="True">
<Image Source="component/Images/test.png"/>
<TextBlock Text="{Binding Path=Name, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
</DockPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DockPanel LastChildFill="True">
<Image Source="component/Images/test.png"/>
<TextBox Text="{Binding Path=Name, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
</DockPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Company" Binding="{Binding Company, ValidatesOnDataErrors=True}" MinWidth="115" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
举一个简单的例子,我怎样才能将Header = Name用于列的相同模板应用于Header = Company的列,而不必为每列重现整个模板?
我找到了this previous SO question的答案,他们使用以下资源来解释:
<Application.Resources>
<DataTemplate x:Key="CellTemplate">
...
</DataTemplate>
<DataTemplate x:Key="CellEdintingTemplate">
...
</DataTemplate>
</Application.Resources>
<DataGrid Style="{StaticResource MainGridStyle}">
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource MyFirstColumnCellTemplate}" CellEdintingTemplate="{StaticResource MyFirstColumnCellEdintingTemplate}"/>
...
</DataGrid.Columns>
<DataGrid>
这让我95%,但我遗失的最后一块是如何处理数据绑定?如何在模板中创建某种类型的占位符,然后在网格中进行实际绑定?
修改 我一直在寻找并发现问题Create Common DataGridTemplateColumn这听起来像我想要做的事实上目前可能是不可能的。因此,如果其他任何人试图这样做,并看到这个问题我不能保证这是不可能的,但从这个链接似乎可能是。因此,只需复制每列的所有tempalte代码。
答案 0 :(得分:8)
您可以将CellStyle
属性设置为覆盖Template
的{{1}}的样式。
在DataGridCell
中,使用Template
绑定到ContentPresenter
的{{1}},因为TemplatedParent.Content
是TemplatedParent
DataGridCell
}
例如,
<Style x:Key="MyCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Image Source="component/Images/test.png"/>
<ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataGrid ItemsSource="{Binding ItemList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" CellStyle="{StaticResource MyCellStyle}" MinWidth="130" Width="Auto" />
<DataGridTextColumn Header="Company" Binding="{Binding Company}" CellStyle="{StaticResource MyCellStyle}" MinWidth="115" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
答案 1 :(得分:1)
链接Create Common DataGridTemplateColumn中有一个解决方案。
Poptart911创建了一个DatagridBoundTemplateColumn,可用于替换DataGridTemplateColumn,允许您在列上设置“Binding”属性。因此,您可以重用DataTemplate并将不同的DataContext分配给不同列的模板。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace OwensWpfFunStuff
{
public class DataGridBoundTemplateColumn : DataGridBoundColumn
{
public DataTemplate CellTemplate { get; set; }
public DataTemplate CellEditingTemplate { get; set; }
protected override System.Windows.FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
return Generate(dataItem, CellEditingTemplate);
}
private FrameworkElement Generate(object dataItem, DataTemplate template)
{
var contentControl = new ContentControl { ContentTemplate = template, Content = dataItem };
BindingOperations.SetBinding(contentControl, ContentControl.ContentProperty, Binding);
return contentControl;
}
protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
return Generate(dataItem, CellTemplate);
}
}
}