2013-02-19 5 views
5

У меня есть таблица WPF, которая имеет собственный заголовок (на основе StackPanel), который включает кнопку, которая отображает и обрабатывает установку единиц для столбца. Что работает хорошо, однако я хочу, чтобы иметь возможность копировать данные в буфер обмена, включая заголовки.Wpf DataGrid ClipboardCopyMode = "IncludeHeader" с настраиваемым заголовком

<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 

Есть ли способ, чтобы изменить то, что текст печатается в заголовке, когда используется специальный заголовок?

ответ

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. Я использовал тег как текст заголовка, так как это было удобно

+0

Спасибо @xerous и да, это действительно работает и для StackPanel. –

1

Я искал решение этой проблемы при использовании HeaderTemplate с текстовым блоком. В моем случае я решил проблему с прикрепленным имуществом. Вы можете видеть, что я просто беру текст из шаблона заголовка и устанавливаю его в свойство заголовка. Таким образом, режим копирования буфера обмена 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

0

Я использовал альтернативный AttachedProperty в связи GetFuzzy в http://waldoscode.blogspot.com/2014/08/issue-using-wpf-datagrid-columnheader.html. Автор (Дон) создал AttachedProperty следующим образом (с парой маленьких модников моих собственных):

/// <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); 
    } 
} 

я не смог заставить его работать при установке Column.Header напрямую, но был в состоянии заставить его работать с HeaderTemplate, как показано ниже:

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

    ... 
</DataGridTemplateColumn> 

СПАСИБО GetFuzzy дЛЯ ОТЛИЧНОГО POST БЛОГ!

Смежные вопросы