Wpf DataGrid ClipboardCopyMode=";IncludeHeader“;带有自定义标题
我有一个WPF表,它有一个自定义标题(基于StackPanel),其中包括一个按钮,用于显示和处理列的单位设置。这很好地工作,但是我希望能够复制数据到剪贴板,包括标题Wpf DataGrid ClipboardCopyMode=";IncludeHeader“;带有自定义标题,wpf,wpfdatagrid,Wpf,Wpfdatagrid,我有一个WPF表,它有一个自定义标题(基于StackPanel),其中包括一个按钮,用于显示和处理列的单位设置。这很好地工作,但是我希望能够复制数据到剪贴板,包括标题 <DataGrid ClipboardCopyMode="IncludeHeader" ... <DataGridTextColumn Header="Some Header" Binding={Binding Path=SomeValue}/> <DataGridTextColumn Binding={B
<DataGrid ClipboardCopyMode="IncludeHeader"
...
<DataGridTextColumn Header="Some Header" Binding={Binding Path=SomeValue}/>
<DataGridTextColumn Binding={Binding Path=OtherValue, Converter="{StaticResource unitsConverter}">
<DataGridTextColumn.Header>
<StackPanel>
<TextBlock Text="Period" />
<Button ... />
</Stackpanel>
使用自定义标题时,是否有方法更改标题打印的文本?我四处寻找解决方案,然后将自定义标题控件子类化,以覆盖
ToString()
,以便ClipboardCopyMode=“IncludeHeader”
复制正确的文本
在我的例子中,我在标题中使用了一个图像:
class HeaderImage : Image
{
public override string ToString()
{
return Tag.ToString();
}
}
Xaml:
现在,复制/粘贴数据已“弃用”,而不是
System.Windows.Controls.Image
。我相信您也可以使用StackPanel
。我使用标记作为标题文本,因为它很方便当使用带有文本块的HeaderTemplate时,我正在寻找解决此问题的方法。在我的情况下,我解决了附带财产的问题。您可以看到,我只是从header模板中获取文本,并将其设置为header属性。这样,剪贴板复制模式IncludeHeader可以按预期工作
/// <summary>
/// WPF Data grid does not know what is in a header template, so it can't copy it to the clipboard when using ClipboardCopyMode="IncludeHeader".
/// This attached property works with a header template that includes one TextBlock. Text content from the templates TextBlock is copied to the
/// column header for the clipboard to pick up.
/// </summary>
public static class TemplatedDataGridHeaderText
{
private static readonly Type OwnerType = typeof(TemplatedDataGridHeaderText);
public static readonly DependencyProperty UseTextFromTemplateProperty = DependencyProperty.RegisterAttached("UseTextFromTemplate", typeof(bool), OwnerType, new PropertyMetadata(false, OnHeaderTextChanged));
public static bool GetUseTextFromTemplate(DependencyObject obj)
{
return (bool)obj.GetValue(UseTextFromTemplateProperty);
}
public static void SetUseTextFromTemplate(DependencyObject obj, bool value)
{
obj.SetValue(UseTextFromTemplateProperty, value);
}
private static void OnHeaderTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textColumn = d as DataGridTextColumn;
if (textColumn == null) return;
if (textColumn.HeaderTemplate == null) return;
var headerTemplateTexblockText = textColumn.HeaderTemplate.LoadContent().GetValue(TextBlock.TextProperty).ToString();
textColumn.Header = headerTemplateTexblockText;
}
}
//
///WPF数据网格不知道标题模板中有什么,因此在使用ClipboardCopyMode=“IncludeHeader”时无法将其复制到剪贴板。
///此附加属性与包含一个文本块的标题模板一起使用。模板文本块中的文本内容将复制到
///剪贴板要拾取的列标题。
///
公共静态类TemplatedDataGridHeaderText
{
私有静态只读类型OwnerType=typeof(TemplatedDataTagridHeaderText);
公共静态只读DependencyProperty UseTextFromTemplateProperty=DependencyProperty.RegisterAttached(“UseTextFromTemplate”、typeof(bool)、OwnerType、new PropertyMetadata(false、OnHeaderTextChanged));
公共静态bool GetUseTextFromTemplate(DependencyObject obj)
{
返回(bool)对象GetValue(UseTextFromTemplateProperty);
}
公共静态无效SetUseTextFromTemplate(DependencyObject对象,布尔值)
{
对象设置值(UseTextFromTemplateProperty,值);
}
私有静态无效OnHeaderTextChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var textColumn=d作为DataGridTextColumn;
if(textColumn==null)返回;
if(textColumn.HeaderTemplate==null)返回;
var headerTemplateTexblockText=textColumn.HeaderTemplate.LoadContent().GetValue(TextBlock.TextProperty.ToString();
text column.Header=headerTemplateTexblockText;
}
}
xaml看起来像这样
<DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False" IsReadOnly="True" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FlowRate.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource FlowRate}"
attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>
<DataGridTextColumn Binding="{Binding Pressure.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource Pressure}"
attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>
</DataGrid.Columns>
更多信息可以在这里找到 我在GetFuzzy的链接中使用了可选的AttachedProperty。作者(Don)创建了一个AttachedProperty,如下所示(带有我自己的几个小mod):
//
///允许将属性绑定到标题文本。使用剪贴板复制模式-IncludeHeaders。
///
公共静态类DataGridHeaderTextAttachedProperty
{
私有静态只读类型OwnerType=typeof(DataGridHeaderTextAttachedProperty);
公共静态只读DependencyProperty HeaderTextProperty=DependencyProperty.RegisterAttached(“HeaderText”,typeof(string),OwnerType,new PropertyMetadata(OnHeaderTextChanged));
公共静态字符串GetHeaderText(DependencyObject obj)
{
返回(字符串)obj.GetValue(HeaderTextProperty);
}
公共静态void SetHeaderText(DependencyObject对象,字符串值)
{
对象设置值(HeaderTextProperty,值);
}
私有静态无效OnHeaderTextChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var column=d作为DataGridColumn;
if(column==null)返回;
column.Header=GetHeaderText(column);
}
}
直接设置列.Header时,我无法使其工作,但可以使其与HeaderTemplate一起工作,如下所示:
<DataGridTemplateColumn ...
ui:DataGridHeaderTextAttachedProperty.HeaderText="Some Text">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Path Data="{StaticResource SomeGeometry}" ... />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
...
</DataGridTemplateColumn>
...
感谢GetFuzzy的精彩博客文章 谢谢@xerous,是的,它确实也适用于StackPanel。
<DataGrid ItemsSource="{Binding }" AutoGenerateColumns="False" IsReadOnly="True" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FlowRate.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource FlowRate}"
attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>
<DataGridTextColumn Binding="{Binding Pressure.UserValue, StringFormat=N3}" HeaderTemplate="{StaticResource Pressure}"
attachedProperties:TemplatedDataGridHeaderText.UseTextFromTemplate="True"/>
</DataGrid.Columns>
/// <summary>
/// Allows binding a property to the header text. Works with the clipboard copy mode - IncludeHeaders.
/// </summary>
public static class DataGridHeaderTextAttachedProperty
{
private static readonly Type OwnerType = typeof(DataGridHeaderTextAttachedProperty);
public static readonly DependencyProperty HeaderTextProperty = DependencyProperty.RegisterAttached("HeaderText", typeof(string), OwnerType, new PropertyMetadata(OnHeaderTextChanged));
public static string GetHeaderText(DependencyObject obj)
{
return (string)obj.GetValue(HeaderTextProperty);
}
public static void SetHeaderText(DependencyObject obj, string value)
{
obj.SetValue(HeaderTextProperty, value);
}
private static void OnHeaderTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var column = d as DataGridColumn;
if (column == null) return;
column.Header = GetHeaderText(column);
}
}
<DataGridTemplateColumn ...
ui:DataGridHeaderTextAttachedProperty.HeaderText="Some Text">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Path Data="{StaticResource SomeGeometry}" ... />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
...
</DataGridTemplateColumn>