Question

There is good default feature in WPF DataGrid, which copies selected cells into Clipboard, so we can use it in other applications. But it seems, that copy process can be improved in terms of performance and also there is some kind of ... bug during paste into excel I assume, needs to be fixed.


Steps to replicate bug (incorrect excel usage)

A.1) copy cells from WPF DataGrid, containing text values with and without leading zeros (e.g. "001"; "002"; "1"; "12345"; "ABC"; "0ABC")

A.2) paste copied data into excel. It is expected, that leading zeroes will be kept, but if possible, excel will convert numeric values to numeric data format (by default cell data type is General, which does the thing).


Steps to replicate bug (correct excel usage)

B.1) copy cells from WPF DataGrid, containing text values with and without leading zeros (e.g. "001"; "002"; "1"; "12345"; "ABC"; "0ABC")

B.2) select all cells in target excel file and change cells data type to Text

B.3) paste copied data into excel. It is expected, that leading zeroes will be kept, but they are gone as well!


Steps to see expected result in excel (correct excel usage)

C.1) copy the same data from Notepad to clipboard

C.2) select all cells in target excel file and change cells data type to Text

C.3) paste copied data into excel. It is expected, that leading zeroes will be kept and now it is true. We can see identical to the source data. WYSIWYG


I started to look into Clipboard data to find the difference between B.1 and C.1 (I also copied the same data from excel and checked out it as well...). What I found out with help of C# Clipboard Viewer Sample from Microsoft:

Clipboard Data Formats for data, copied from Notepad++:

            - Text (native)

            - UnicodeText (native)

            - System.String (autoconvertable)

            - Locale (native)

            - OEMText (native)

Clipboard Data Formats for data, copied from WPF DataGrid:

            - HTML Format (native)

            - Csv (native)

            - Text (native)

            - UnicodeText (native)

            - System.String (autoconvertable)

Clipboard Data Formats for data, copied from 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)

So what would be the good\best way to solve problem on step B.3? I am wondering about 2 options for now:

Option #1

find out the way to explain to wpf datagrid, that it needs to set data into clipboard in a specific format.

Option #2

Second option is to handle Ctrl+C with my own function, which will run through selected cells, talk to view behind the datagrid, get correct data, append to string builder and set text to the clipboard.

And what do you think will be the best solution for the above B.3?

Was it helpful?

Solution

Ok. So since I am talking about copy from WPF DataGrid into clipboard... I looked into the source code of the datagrid (I should come up with this idea before and not ask this question.)

so, part of handler for copy in the source is :

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

so simple answer is: Option #1 is not possible (in other words - sinse data formats for clipboard are hard coded - no possibility to influence that). Option #2 is ok. But now I think that is make sense to inherit datagrid and override method

        protected virtual void OnExecutedCopy(ExecutedRoutedEventArgs args)

this will give me good solution for all cases.

OTHER TIPS

I found that DataFormats.Html is the problem. Change the Excel destination cell format text.

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top