WPF数据表格复制到剪贴板:如何影响剪贴板中的数据格式?

4
WPF DataGrid中有一个很好的默认功能,可以将选定的单元格复制到剪贴板中,以便在其他应用程序中使用。但似乎复制过程在性能方面需要改进,而且还存在一些...粘贴到Excel时的错误,我想需要修复。
复制错误的步骤(不正确的Excel使用):
A.1)从WPF DataGrid中复制包含文本值和不带前导零的单元格(例如“001”、“002”、“1”、“12345”、“ABC”、“0ABC”)。
A.2)将已复制的数据粘贴到Excel中。预期前导零将被保留,但如果可能的话,Excel会将数字值转换为数字数据格式(默认情况下,单元格数据类型为通用类型)。
复制错误的步骤(正确的Excel使用):
B.1)从WPF DataGrid中复制包含文本值和不带前导零的单元格(例如“001”、“002”、“1”、“12345”、“ABC”、“0ABC”)。
B.2)选择目标Excel文件中的所有单元格并更改单元格数据类型为文本。
B.3)将已复制的数据粘贴到Excel中。它预期前导零将被保留,但它们也消失了!
查看Excel中预期结果的步骤(正确使用Excel):
C.1)从记事本中将相同的数据复制到剪贴板中。
C.2)选择目标Excel文件中的所有单元格并更改单元格数据类型为文本。
C.3)将已复制的数据粘贴到Excel中。预期前导零将被保留,现在它成立了。我们可以看到与源数据相同。所见即所得。
我开始查看剪贴板数据,以找出B.1和C.1之间的差异(我还从Excel中复制了相同的数据并进行了检查...)。通过使用Microsoft提供的C# Clipboard Viewer示例,我发现了以下内容:
从记事本++复制的数据的剪贴板数据格式:
            - Text (native)

            - UnicodeText (native)

            - System.String (autoconvertable)

            - Locale (native)

            - OEMText (native)

复制自 WPF DataGrid 的数据的剪贴板数据格式:

            - HTML Format (native)

            - Csv (native)

            - Text (native)

            - UnicodeText (native)

            - System.String (autoconvertable)

从Excel复制的数据的剪贴板数据格式:

            - EnhancedMetafile (native)

            - System.Drawing.Imaging.Metafile (autoconvertable)

            - MetaFilePict (native)

            - Bitmap (native)

            - System.Drawing.Bitmap (autoconvertable)

            - System.Windows.Media.Imaging.BitmapSource (autoconvertable)

            - Biff12 (native)

            - Biff8 (native)

            - Biff5 (native)

            - SymbolicLink (native)

            - DataInterchangeFormat (native)

            - XML Spreadsheet (native)

            - HTML Format (native)

            - Text (native)

            - UnicodeText (native)

            - System.String (autoconvertable)

            - Csv (native)

            - Hyperlink (native)

            - Rich Text Format (native)

            - Embed Source (native)

            - Object Descriptor (native)

            - Link Source (native)

            - Link Source Descriptor (native)

            - Link (native)

            - Format129 (native)

那么,解决B.3步骤的好方法或最佳方法是什么呢?目前我考虑了两个选项:

选项#1

找出一种方法来向wpf数据网格解释,它需要以特定格式将数据设置到剪贴板中。

选项#2

第二个选项是使用自己的函数处理Ctrl+C,该函数将运行通过选择的单元格,与数据网格背后的视图进行通信,获取正确的数据,附加到字符串生成器并将文本设置到剪贴板。

那么您认为上述B.3的最佳解决方案是什么?


  1. 明确的问题是“如何解决B部分描述的意外行为,项目B.3”。
  2. 很明显我不会,但是从程序上来说有A和B部分之间的区别 - 你需要正确使用Excel。在我们粘贴之前使用文本数据类型。这样我们就可以对此进行一些控制。
  3. 谢谢,这将进入我心中的第二个选项,请不要发布任何其他链接,我知道如何将数据复制到剪贴板中 :-)
- LOCKI
清晰明了的回答:除非你是Excel的开发人员,否则就像我刚才提到的那样,“你无法控制一个对象如何被粘贴到Excel或其他任何应用程序中”……粘贴功能是在接收剪贴板数据的应用程序中实现的,因此你所能做的最好的办法就是找出Excel可以接受的数据类型,并手动将你的数据放入该格式中(使用我在上一条评论中提供的链接)。 - Sheridan
亲爱的谢里丹,我并不是在询问关于Excel的问题。我想问的是如何将WPF DataGrid中的数据以与记事本相同的方式复制到剪贴板中。现在清楚了吗?我还想建议您复制第3节中描述的步骤。您会发现,可以按预期将数据复制和粘贴到Excel中,而不会丢失前导零=无需更改Excel。 - LOCKI
还有一件事:“除非你开发了Excel,否则就像我刚才提到的那样,你无法控制对象如何粘贴到Excel或任何其他应用程序中。” 这是真的,只有从一个单一的角度来看 - 程序员的角度。从普通用户的角度来看,当然可以控制数据如何粘贴到Excel中。这种控制仅限于向最终用户公开使用的功能(其中之一是更改目标单元格的数据类型)。 - LOCKI
我完全理解你的问题,并已经向你提供了信息,以帮助你在你的努力中取得成功。 - Sheridan
显示剩余2条评论
2个回答

3

好的。因为我正在谈论从WPF DataGrid复制到剪贴板,所以我查看了datagrid的源代码(我应该在之前想到这个主意并且不问这个问题)。

所以,在源码中处理复制的部分如下:

        // Supported default formats: Html, Text, UnicodeText and CSV
        Collection<string> formats = new Collection<string>(new string[] { DataFormats.Html, DataFormats.Text, DataFormats.UnicodeText, DataFormats.CommaSeparatedValue });

如此简单的答案是:选项#1不可行(换句话说-由于剪贴板的数据格式是硬编码的,因此无法影响)。选项#2是可以的。但现在我认为继承datagrid并覆盖方法是有意义的。
        protected virtual void OnExecutedCopy(ExecutedRoutedEventArgs args)

这将为我提供所有情况的良好解决方案。

不错的话题。如果您无法复制那些不是自动递增的PK列怎么办?对我来说,当我像这样复制带有PK的完整行时,它会跳到另一行。 - Emil

0
我发现DataFormats.Html是问题所在。更改Excel目标单元格的格式文本。
protected override void OnExecutedCopy(ExecutedRoutedEventArgs args)
{
    base.OnExecutedCopy(args);
    var data = Clipboard.GetDataObject();
    DataObject dataObject = new DataObject();
    foreach (var format in data.GetFormats())
    {
        //We copy all formats, but DataFormats.Html,
        //DataFormats.Html messed up paste in Excel very long number (15 pos +) and leading zero's
        //You need to set the cell format to text before paste
        if (format != DataFormats.Html)
            dataObject.SetData(format, data.GetData(format), true);
    }
    Clipboard.SetDataObject(dataObject);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接