C # копирование и вставка объекта

#c# #serialization #clipboard

#c# #сериализация #буфер обмена

Вопрос:

Итак, я пытаюсь скопировать и вставить объект и не могу сделать это правильно. Я просмотрел разделы, но, похоже, все еще не могу заставить это работать. Вот код:

В одном решении в Visual Studio у меня есть класс:

 namespace test4
{
    [Serializable]
    public class copypaste
    {
        public string test = "a";
    }
}
  

и копирование части кода:

 private void btn1_Click(object sender, EventArgs e)
{
        var copy_obj = new copypaste();
        DataObject d = new DataObject(copy_obj);
        Clipboard.SetDataObject(d);
}
  

И в другом решении у меня есть:

 namespace test4
{
    [Serializable]
    public class copypaste
    {
        public string test = "a";
    }
}
  

и вставляемая часть кода:

 private void btnTest_Click(object sender, EventArgs e)
{
    var d = Clipboard.GetDataObject();
    if (d.GetDataPresent("test4.copypaste"))
    {
        var o = d.GetData("test4.copypaste");
        Debug.WriteLine( ( (copypaste)o ).test );
    }
}
  

Однако в конечном итоге я получаю следующую ошибку в последней строке:
‘Система.Исключение InvalidCastException: ‘Невозможно преобразовать объект типа ‘System.IO.MemoryStream’ в тип ‘test4.copypaste’.’

Я рассмотрел другие вопросы, которые предлагают этот способ копирования / вставки кода, но, похоже, ни один из них не возвращает поток памяти при вызове метода getData. Я не уверен, как извлечь объект из потока памяти.

Спасибо

Комментарии:

1. вы не передали объект в потоковую передачу MemoryStream. Ваш код ничего не сериализует.. вы просто помещаете объект в буфер обмена.

2. В конце концов, вам придется использовать setData , если вы используете GetData с пользовательским форматом

3. Вам необходимо определить пользовательский формат данных при сохранении данных в буфер обмена. Проверьте пример здесь: learn.microsoft.com/it-it/dotnet/api/… В вашем случае это было бы что-то вроде: DataFormats. Формат myFormat = DataFormats. getFormat(«test4.copypaste»); переменная copy_obj = новая copypaste(); Объект данных MyDataObject = новый объект данных(myFormat.Name , copy_obj); Буфер обмена. SetDataObject(MyDataObject);

Ответ №1:

С учетом этой ссылки и вашего сериализуемого класса это работает так, как ожидалось:

 private void copyButton_Click(object sender, EventArgs e)
    {
        DataFormats.Format myFormat = DataFormats.GetFormat("test4.copypaste");
        var copy_obj = new copypaste();

        DataObject myDataObject = new DataObject(myFormat.Name, copy_obj);
        Clipboard.SetDataObject(myDataObject);
    }

    private void pasteButton_Click(object sender, EventArgs e)
    {
        var d = Clipboard.GetDataObject();
        if (d.GetDataPresent("test4.copypaste"))
        {
            var o = d.GetData("test4.copypaste");
            Debug.WriteLine(((copypaste)o).test);
        }
    }
  

Комментарии:

1. Для меня это работает как шарм. Проверьте это: ссылка . В этом новом примере я просто добавил конструктор к вашему сериализуемому классу: public copypaste(строка t) { test = t; }, а затем в copyButton_Click я изменил создание экземпляра copy_obj следующим образом: var copy_obj = new copypaste(copyTextBox.Text); В pasteButton_Click вместо этого изменил Debug. Строка записи с помощью: pasteLabel. Текст = ((copypaste)o).тест; Полный код здесь, ссылка

2. Спасибо, что вернулись. Да, это работает и для меня, если я использую функции копирования и вставки в одном решении, моя проблема, когда я помещаю функцию копирования в одно решение, а функцию вставки в другое….

3. Я попробовал этот подход в том же решении: — создал проект библиотеки с классом copypaste в нем — создал проект приложения WinForms, ссылающийся на проект библиотеки, и вставил «CopyButton» — создал проект приложения WinForms, ссылающийся на проект библиотеки, и вставил «pasteButton», И он работает должным образом! Перечитывая ваш вступительный пост, я думаю, проблема в том, что вы скопировали-вставили класс. Для .NET это два разных класса, независимо от того, какова их сигнатура и / или пространство имен. Если вам нужно использовать два решения, вы должны совместно использовать dll с классом.

4. Ну ладно, тогда это ответ на этот вопрос. Спасибо!