带有自定义标头的Wpf DataGrid ClipboardCopyMode =“IncludeHeader”

时间:2013-02-19 02:00:35

标签: wpf wpfdatagrid

我有一个WPF表,它有一个自定义标题(基于StackPanel),其中包含一个按钮,用于显示和处理设置列的单位。这很好用,但我希望能够将数据复制到剪贴板,包括标题。

<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>

问题是具有自定义标题的列复制到剪贴板

SomeHeader System.Windows.Controls.StackPanel
v1         33

有没有办法在使用自定义标题时更改标题的打印文字?

3 个答案:

答案 0 :(得分:6)

我探索了一个解决方案然后结束了我的自定义标头控件的子类,只是为了覆盖ToString(),以便ClipboardCopyMode="IncludeHeader"复制正确的文本。

在我的情况下,我在标题中使用了一个图像:

class HeaderImage : Image
{
    public override string ToString()
    {
        return Tag.ToString();
    }
}

的Xaml:

 <DataGridCheckBoxColumn.Header>
     <elements:HeaderImage Source="..\Resources\skull.png" Width="15" Tag="Deprecated"/>
 </DataGridCheckBoxColumn.Header>

现在复制/粘贴数据已“弃用”而不是System.Windows.Controls.Image。我相信你可以对StackPanel做同样的事情。我使用Tag作为标题文本,因为它很方便

答案 1 :(得分:1)

在使用包含文本块的HeaderTemplate时,我一直在寻找这个问题的解决方案。在我的情况下,我解决了附加财产的问题。您可以看到我只是从标题模板中获取文本,并将其设置为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;  
 }  
}  

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>  

可在此处找到更多信息... http://waldoscode.blogspot.com/2014/08/issue-using-wpf-datagrid-columnheader.html

答案 2 :(得分:0)

我在GetFuzzy的链接http://waldoscode.blogspot.com/2014/08/issue-using-wpf-datagrid-columnheader.html中使用了替代的AttachedProperty。作者(Don)创建了一个AttachedProperty如下(我自己的几个小mod):

<DataGridTemplateColumn ...
                        ui:DataGridHeaderTextAttachedProperty.HeaderText="Some Text">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <Path Data="{StaticResource SomeGeometry}" ... />
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>

    ...
</DataGridTemplateColumn>

直接设置Column.Header时我无法让它工作但是能够让它与HeaderTemplate一起使用,如下所示:

Shoes

感谢GetFuzzy以获得优秀的博客文章!