Niedawno uaktualniliśmy bardzo duży projekt z platformy .NET 3.5-4, a początkowo wszystko działało tak samo. Ale teraz zaczęły pojawiać się błędy w operacjach wklejania kopii. Udało mi się zrobić małą, odtwarzalną aplikację, która pokazuje różne zachowanie w .NET 3.5 i 4. Znalazłem również obejście (ręcznie serializować dane do schowka), ale muszę wiedzieć "dlaczego" istnieje różnica w zachowaniu.Schowek zachowuje się inaczej w .NET 3.5 i 4, ale dlaczego?
Jest to mała aplikacja Test zrobiłem:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace ClipboardTest
{
public class Program
{
[Serializable]
public class Element
{
public Element(string name)
{
this.name = name;
}
public string name;
}
public static List<Element> TestSerializer(List<Element> obj)
{
var memoryStream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, obj);
return (List<Element>)formatter.Deserialize(new MemoryStream(memoryStream.GetBuffer()));
}
public static List<Element> TestClipboard(List<Element> obj)
{
Clipboard.SetDataObject(obj);
return (List<Element>)Clipboard.GetDataObject().GetData(typeof(List<Element>));
}
public static void DumpObject(string testName, List<Element> obj)
{
if (obj == null)
{
Console.WriteLine("{0} : List is null", testName);
return;
}
foreach (var prop in obj)
{
Console.WriteLine("{0} : {1}", testName, prop.name);
}
}
[STAThread]
static void Main()
{
var copyData = new List<Element> { new Element("all good") };
DumpObject("Serializer", TestSerializer(copyData));
DumpObject("Clipboard", TestClipboard(copyData));
}
}
}
.NET 3.5 wyjście:
serializer: wszystko dobre
Schowek: wszystko dobre
.NET 4 wyjścia:
serializer : wszystkie dobre
Schowek: lista jest pusta
Spojrzałem na źródło .NET dla klasy Schowek & DataObject, ale nie widziałem, który serializator został użyty. Dokumentacja MSDN mówi, że typ musi być możliwy do serializacji, co w tym przypadku ma zarówno klasę List <>, jak i Element. Kopiowanie obiektu Element działa dobrze, ale jak tylko skopiuję listę elementów, zepsuje się.
Aby przetestować, stworzyłem 2 projekty C# "Console Application" w Visual Studio 2010 SP1. Pierwszy projekt, który pozostał przy domyślnym ustawieniu "Struktura docelowa" "Profil klienta .NET Framework 4". Drugi projekt, który zmodyfikowałem, aby korzystać z "profilu klienta .NET Framework 3.5".
Dodatkowe informacje o moich formularzy DLL wersji:
Original filename: System.Windows.Forms.dll
wersja Plik/wersja prouct: 4.0.30319.235
Język: Angielski (Stany Zjednoczone)
Data modyfikacji: 16 -02-2012 22:50
Dla mnie działa dobrze z .NET 4 ... drukuje "wszystko dobrze" dla obu przypadków –
Hm, na moim komputerze, działa dobrze z 3.5 i kończy się niepowodzeniem na 4.0 ustawiony jako ramka docelowa, podobnie jak OP states (zgłasza wyjątek COM "Invalid FORMATETC structure" w Clipboard.GetDataObject(). GetData()). Również znalazłem podobny problem tutaj: https://connect.microsoft.com/VisualStudio/feedback/details/488627/comexception-invalid-formatetc-structure-while-pasting-marshalbyref-data-from-datagridview – Alan
(przy użyciu VS2010 SP1 na XP SP3) – Alan