WPF,DataGrid,ClipboardCopyMode取决于复制的列数

时间:2018-01-16 19:12:02

标签: wpf datagrid

在我的WPF DataGrid中,我正在使用这组属性值:

  • ClipboardCopyMode = “IncludeHeader”
  • SelectionUnit = “CellOrRowHeader”
  • 的SelectionMode = “扩展”

好:当用户在数据网格的多个列中选择并复制单元格时,它会包含标题信息。他很满意。他可以将单元格粘贴到Excel中,并且没有关于列的歧义。

错误:当用户选择并复制单个单元格时,他不希望包含标题。他可能会将单个单元格值粘贴到另一个应用程序中。它不应该包含该标题。 (当他从一列复制一系列单元格时,他有相同的偏好。)

我该如何实现?

2 个答案:

答案 0 :(得分:1)

我是这样做的:

  • 订阅DataGrid的OnCopyingRowClipboardContent活动。
  • 请注意,OnCopyingRowClipboardContent事件会对复制操作中涉及的每一行触发一次,包括标题行。
  • 当标题行触发事件时,如果复制操作中只包含一列,请将其删除。

我正在使用F#:

if args.IsColumnHeadersRow then
    let isMultiColumnSelection = (args.EndColumnDisplayIndex - args.StartColumnDisplayIndex) > 0
    if not isMultiColumnSelection then
        args.ClipboardRowContent.RemoveAll(fun c -> true) |> ignore

答案 1 :(得分:1)

语言:C#

我刚遇到这个问题,它帮助我解决了问题,所以我也想分享我的解决方案。


如果仅选择所有列,我只想复制标题。

  • 我正在使用附加的行为,该行为将订阅CopyingRowClipboardContent
  • 在事件中,我检查行是否为IsColumnHeadersRow
  • 我还要检查是否同时选择了第一列和最后一列

(这不是100%准确的,因为用户可以选择第一列和最后一列,而不必选择列,但就我而言,这已经足够了)


我的行为

public class DataGridCopyBehaviour : Behavior<DataGrid> {
    protected override void OnAttached() {
        base.OnAttached();

        AssociatedObject.CopyingRowClipboardContent += (object sender, DataGridRowClipboardEventArgs e) => {
            if(e.IsColumnHeadersRow && (e.StartColumnDisplayIndex != 0 || e.EndColumnDisplayIndex != ((DataGrid)sender).Columns.Count - 1))
                e.ClipboardRowContent.Clear();
        };
    }
}

我的Datagrid:

<DataGrid IsReadOnly="True" AutoGenerateColumns="False" SelectionUnit="CellOrRowHeader" ClipboardCopyMode="IncludeHeader"
          ItemsSource="{Binding ...}">

    <i:Interaction.Behaviors>
        <u:DataGridCopyBehaviour/> 
    </i:Interaction.Behaviors>

    <DataGrid.Columns>
        ...
    </DataGrid.Columns>
</DataGrid>

注意:

EventHandler也可以在没有行为的情况下工作!我想使用一种行为来保持我的MVVM-Design干净。

您可以在任何地方使用此代码:

MyDataGrid.CopyingRowClipboardContent += (object sender, DataGridRowClipboardEventArgs e) => {
    if(e.IsColumnHeadersRow && (e.StartColumnDisplayIndex != 0 || e.EndColumnDisplayIndex != ((DataGrid)sender).Columns.Count - 1))
        e.ClipboardRowContent.Clear();
};