【问题标题】:WPF DataGrid copy to clipboard: how to influence data formats in the clipboard?WPF DataGrid 复制到剪贴板:如何影响剪贴板中的数据格式?
【发布时间】:2014-05-14 07:39:25
【问题描述】:

WPF DataGrid 中有一个很好的默认功能,可以将选定的单元格复制到剪贴板中,因此我们可以在其他应用程序中使用它。但似乎,复制过程在性能方面可以得到改进,而且我认为在粘贴到 excel 过程中存在某种 ... 错误,需要修复。


复制错误的步骤(不正确的 excel 用法)

A.1) 从 WPF DataGrid 复制单元格,包含带和不带前导零的文本值(例如“001”;“002”;“1”;“12345”;“ABC”;“0ABC”)

A.2) 将复制的数据粘贴到 Excel 中。预计会保留前导零,但如果可能,excel 会将数值转换为数值数据格式(默认情况下,单元格数据类型为 General,它会执行此操作)。


复制错误的步骤(正确使用 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 Sample 的帮助下发现了什么:

数据的剪贴板数据格式,从 Notepad++ 复制:

            - 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 中解决问题的最佳\最佳方法是什么?我现在想知道 2 个选项:

选项#1

找到向 wpf datagrid 解释的方法,它需要以特定格式将数据设置到剪贴板中。

选项 #2

第二个选项是使用我自己的函数来处理 Ctrl+C,它将遍历选定的单元格,与数据网格后面的视图对话,获取正确的数据,附加到字符串生成器并将文本设置到剪贴板。

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

【问题讨论】:

  • 1.请提出一个实际明确的问题。 2. 您无法控制如何将对象粘贴到 Excel 中。 3. 您可以将数据以您想要的任何格式存储到剪贴板中...请参阅 MSDN 上的How to: Add Data to the Clipboard 页面。
  • 1.明确的问题是“如何解决意外行为,这在 B 部分中进行了描述。项目 B.3” 2. 显然我没有,但以编程方式。 A部分和B部分之间存在差异-您需要正确使用excel。在我们粘贴之前使用文本数据类型。所以我们对此有一些控制权。 3. 谢谢,这是我想到的选项#2,请不要发布任何额外的链接,我知道如何将数据复制到剪贴板:-)
  • 明确回答:除非您开发了 Excel,否则正如我刚才提到的,您无法控制如何将对象粘贴到 Excel 中...或任何其他应用程序。粘贴功能是在接收剪贴板数据的应用程序中实现的,因此您可以做的最好的事情是找出 Excel 可以接受的数据类型,然后手动将您的数据转换为该格式(使用我在上一篇文章中提供的链接评论)。
  • 亲爱的谢里登。我不是在问excel。完全没有。我正在询问以与记事本相同的方式将数据从 WPF DataGrid 复制到剪贴板。现在对你来说够清楚了吗?我还想建议您复制第 3 节中描述的步骤。您将看到,可以按预期将数据复制并粘贴到 excel 中,而不会丢失前导零 = 无需更改 excel。
  • 还有一件事:“除非您开发了 Excel,否则正如我刚才提到的,您无法控制如何将对象粘贴到 Excel...或任何其他应用程序中。”这是真的,只有在你只从一个单一的观点——程序员的观点——来看这个的情况下。从普通用户的角度来看,您当然可以控制如何将数据粘贴到 Excel 中。此控件仅限于功能,公开给最终用户使用(其中之一是更改目标单元格数据类型)。

标签: wpf excel datagrid clipboard


【解决方案1】:

好的。所以既然我说的是从 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 没问题。但是现在我认为继承数据网格和覆盖方法是有意义的

        protected virtual void OnExecutedCopy(ExecutedRoutedEventArgs args)

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

【讨论】:

  • 好话题。如果您在复制那些不会自动递增的 PK 列时遇到任何问题?对我来说,当我像这样用PK复制fullrow时,它会跳转到另一行。
【解决方案2】:

我发现 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 2012-12-02
    • 2013-10-17
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多