简体   繁体   中英

C# Cut/Copy & Paste objects

This is a 2 parter.

First I am having a heck of a time getting the paste part of a copy and paste operation to work.

I have a method that copies information to the Clipboard, works perfectly.

private void CopyData(string format, object data, string text)
    {
        bool addedData = false;
        DataObject copyData = new DataObject();

        if (!string.IsNullOrEmpty(text))
        {
            copyData.SetData(DataFormats.Text, text);
            addedData = true;
        }

        if (!string.IsNullOrEmpty(format) && data != null)
        {
            copyData.SetData(format, false, data);
            addedData = true;

            //this is only for testing
            object obj = null;
            if (copyData.GetDataPresent(format))
                obj = (object)copyData.GetData(format);
        }

        if (addedData)
            Clipboard.SetDataObject(copyData, true);
    }

When I check that the data was added the object (obj) is not null.

However when I then go to paste the data from a different method using the same format key I get null, every time.

private void PasteFromClipboard()
    {
        object obj = null;
        IDataObject paste = null;
        if (Clipboard.GetDataObject().GetDataPresent("mydatatype"))
            obj = (object)Clipboard.GetDataObject().GetData("mydatatype");
        else
            return;

        if (obj == null)
            throw new NullReferenceException("Could not gather information from the 
    }

I have tried everything that I can think of and it just doesn't make sense. I created an array of strings to capture all of the format keys the DataObject was holding and "mydatatype" was the first one. I have tried casting, not casting, using (Clipboard.GetDataObject().GetData("mydatatype") as object) and I just cannot figure it out. I know that there is data there because I can go to NotePad and paste the text that I copied along with the object.

Any thoughts as to why I would be able to get the data in one method, but not another?

Secondly I was wondering how I would go about making a Cut & Paste operation work between two of my windows. I am thinking about something like Excel, where if only the text is pasted the data will remain, however if the objects are pasted then the source will be deleted.

Thanks Patrick.

Try pulling the data out as Text (instead of "mydatatype") - at least to confirm you can read from the clipboard. This is most likely what Notepad is reading. Also, does it matter that you're copying with "format" but pasting with "mydatatype"?

Could it be that text parameter always has a value and gets set. Then possibly the second if the one that would set the object does not get executed. Or if it does since the data was set in the first if statement the second set fails to set it correctly.

My recommendation would be to walk the code in the debugger during the copy operation.

Before the paste use GetDataObject().GetFormats() to enumerate the list of formatting codes. Perhaps your using the wrong one.. just an idea

Try using reflection like this:

    private static T TryGetClipboardData<T>(IDataObject clipboardData, string dataFormat)
    {
        System.Reflection.FieldInfo fieldInfo = clipboardData.GetType().GetField("innerData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var outerData = fieldInfo.GetValue(clipboardData);

        if (outerData == null)
        {
            return default(T);
        }

        fieldInfo = outerData.GetType().GetField("innerData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var innerData = fieldInfo.GetValue(outerData);

        if (innerData is System.Runtime.InteropServices.ComTypes.IDataObject)
        {
            // It is (probably) necessary to wrap COM IDataObject to Windows.Forms.IDataObject
            System.Windows.Forms.DataObject wrappedDataObject = new System.Windows.Forms.DataObject(innerData);

            var data = wrappedDataObject.GetData(dataFormat);

            if (data is T)
            {
                return (T)data;
            }
        }

        return default(T);
    }

I suspect the COM object of your data in the Clipboard had a difficult time converting itself to the format you specified. I'm also playing safe with the input format string so that it is registered as a proper clipboard format.

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM