Kod koji sledi cita tu strukturu sa clipboard-a i prikazuje sta se u njoj nalazi.
Pre pokretanja koda, na formu nabacajte neke kontrole, selektujete ih i zatim kopirajte. Ovaj kod ce prikazati sta se nalazi na cliboardu.
Code (csharp):
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Xml.Serialization;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
DisplayString(ObjectToString(DeserializeFromClipboard()), false);
}
private const string CF_DESIGNERCOMPONENTS_V2 = "CF_DESIGNERCOMPONENTS_V2";
public static ICollection DeserializeFromClipboard()
{
if (Clipboard.ContainsData(CF_DESIGNERCOMPONENTS_V2)) {
byte[] bytes = Clipboard.GetData(CF_DESIGNERCOMPONENTS_V2) as byte[];
if (bytes != null && bytes.Length > 0) {
var bf = new BinaryFormatter();
SerializationStore store = null;
using (var ms = new MemoryStream(bytes)) {
store = bf.Deserialize(ms) as SerializationStore;
}
if (store != null) {
var mgr = new DesignerSerializationManager();
var svc = new CodeDomComponentSerializationService(mgr);
ICollection items = svc.Deserialize(store);
store.Close();
return items;
}
}
}
return null;
}
/// <summary>
/// Debug method, displays string in a dialog.
/// </summary>
public static void DisplayString(string str, bool wordWrap)
{
Form form = null;
TextBox textBox = null;
try {
form = new Form();
textBox = new TextBox();
textBox.Multiline = true;
textBox.Dock = DockStyle.Fill;
textBox.ScrollBars = ScrollBars.Both;
textBox.WordWrap = wordWrap;
textBox.Font = new Font("Courier New", 12);
form.Controls.Add(textBox);
textBox.Text = str;
textBox.ReadOnly = true;
textBox.SelectionLength = 0;
form.Size = new Size(800, 600);
form.Name = "DebugHelper_DisplayString";
form.StartPosition = FormStartPosition.CenterScreen;
form.ShowDialog();
} catch { }
try { if (textBox != null) textBox.Dispose(); } catch { }
try { if (form != null) form.Dispose(); } catch { }
}
public static string ObjectToString(object obj)
{
return ObjectToString(obj, 0, new List<object>());
}
public static string ObjectToString(object obj, int indent, List<object> processed)
{
if (obj != null) {
var s = new System.Text.StringBuilder();
Type type = obj.GetType();
string ind = new string(' ', indent);
if (obj is ICollection) {
var items = (ICollection)obj;
s.AppendLine(string.Format("ICollection({0}): {1} {{", type.FullName, items.Count));
int index = 0;
foreach (object item in items) {
string no = string.Format(" {0}: ", index++);
s.AppendLine(string.Format("{0}{1}{2}", ind, no, ObjectToString(item, indent + no.Length, processed)));
}
s.Append(string.Format("{0}}}", ind));
return s.ToString();
} else if (obj is System.String || type.IsValueType || type.IsEnum) {
return string.Format("Value({0}): {1}", type.FullName, obj);
} else if (type.IsClass) {
if (!processed.Contains(obj)) {
processed.Add(obj);
s.AppendLine(string.Format("Class({0}) {{", type.FullName));
foreach (PropertyDescriptor p in TypeDescriptor.GetProperties(obj)) {
string name = string.Format(" {0}: ", p.Name);
s.AppendLine(string.Format("{0}{1}{2}", ind, name, ObjectToString(p.GetValue(obj), indent + name.Length, processed)));
}
s.Append(string.Format("{0}}}", ind));
return s.ToString();
}
return "already processed";
} else {
return string.Format("Unknown type: {0}", type.FullName);
}
}
return "null";
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Xml.Serialization;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
DisplayString(ObjectToString(DeserializeFromClipboard()), false);
}
private const string CF_DESIGNERCOMPONENTS_V2 = "CF_DESIGNERCOMPONENTS_V2";
public static ICollection DeserializeFromClipboard()
{
if (Clipboard.ContainsData(CF_DESIGNERCOMPONENTS_V2)) {
byte[] bytes = Clipboard.GetData(CF_DESIGNERCOMPONENTS_V2) as byte[];
if (bytes != null && bytes.Length > 0) {
var bf = new BinaryFormatter();
SerializationStore store = null;
using (var ms = new MemoryStream(bytes)) {
store = bf.Deserialize(ms) as SerializationStore;
}
if (store != null) {
var mgr = new DesignerSerializationManager();
var svc = new CodeDomComponentSerializationService(mgr);
ICollection items = svc.Deserialize(store);
store.Close();
return items;
}
}
}
return null;
}
/// <summary>
/// Debug method, displays string in a dialog.
/// </summary>
public static void DisplayString(string str, bool wordWrap)
{
Form form = null;
TextBox textBox = null;
try {
form = new Form();
textBox = new TextBox();
textBox.Multiline = true;
textBox.Dock = DockStyle.Fill;
textBox.ScrollBars = ScrollBars.Both;
textBox.WordWrap = wordWrap;
textBox.Font = new Font("Courier New", 12);
form.Controls.Add(textBox);
textBox.Text = str;
textBox.ReadOnly = true;
textBox.SelectionLength = 0;
form.Size = new Size(800, 600);
form.Name = "DebugHelper_DisplayString";
form.StartPosition = FormStartPosition.CenterScreen;
form.ShowDialog();
} catch { }
try { if (textBox != null) textBox.Dispose(); } catch { }
try { if (form != null) form.Dispose(); } catch { }
}
public static string ObjectToString(object obj)
{
return ObjectToString(obj, 0, new List<object>());
}
public static string ObjectToString(object obj, int indent, List<object> processed)
{
if (obj != null) {
var s = new System.Text.StringBuilder();
Type type = obj.GetType();
string ind = new string(' ', indent);
if (obj is ICollection) {
var items = (ICollection)obj;
s.AppendLine(string.Format("ICollection({0}): {1} {{", type.FullName, items.Count));
int index = 0;
foreach (object item in items) {
string no = string.Format(" {0}: ", index++);
s.AppendLine(string.Format("{0}{1}{2}", ind, no, ObjectToString(item, indent + no.Length, processed)));
}
s.Append(string.Format("{0}}}", ind));
return s.ToString();
} else if (obj is System.String || type.IsValueType || type.IsEnum) {
return string.Format("Value({0}): {1}", type.FullName, obj);
} else if (type.IsClass) {
if (!processed.Contains(obj)) {
processed.Add(obj);
s.AppendLine(string.Format("Class({0}) {{", type.FullName));
foreach (PropertyDescriptor p in TypeDescriptor.GetProperties(obj)) {
string name = string.Format(" {0}: ", p.Name);
s.AppendLine(string.Format("{0}{1}{2}", ind, name, ObjectToString(p.GetValue(obj), indent + name.Length, processed)));
}
s.Append(string.Format("{0}}}", ind));
return s.ToString();
}
return "already processed";
} else {
return string.Format("Unknown type: {0}", type.FullName);
}
}
return "null";
}
}
}
Naredni kod radi suprotnu stvar, pokusava da na cliboard postavi strukturu koja moze da se pastuje u windows form designer-u.
Code (csharp):
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Xml.Serialization;
namespace WindowsFormsApplication2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
var items = new ArrayList();
items.Add(new Button() { Name = "button1", Text = "button1", Location = new Point(0, 0), Size = new Size(50, 20) });
items.Add(new Button() { Name = "button2", Text = "button2", Location = new Point(0, 20), Size = new Size(50, 20) });
items.Insert(0, new string[] { "button1", "button2" });
SerializeToClipboard(items);
}
private const string CF_DESIGNERCOMPONENTS_V2 = "CF_DESIGNERCOMPONENTS_V2";
public static void SerializeToClipboard(ICollection collection)
{
if (collection != null && collection.Count > 0) {
var bf = new BinaryFormatter();
var mgr = new DesignerSerializationManager();
var svc = new CodeDomComponentSerializationService(mgr);
var store = svc.CreateStore();
foreach (object obj in collection) {
svc.Serialize(store, obj);
}
store.Close();
using (var ms = new MemoryStream()) {
bf.Serialize(ms, store);
byte[] bytes = ms.ToArray();
Clipboard.SetDataObject(new DataObject(CF_DESIGNERCOMPONENTS_V2, bytes), true);
}
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Xml.Serialization;
namespace WindowsFormsApplication2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
var items = new ArrayList();
items.Add(new Button() { Name = "button1", Text = "button1", Location = new Point(0, 0), Size = new Size(50, 20) });
items.Add(new Button() { Name = "button2", Text = "button2", Location = new Point(0, 20), Size = new Size(50, 20) });
items.Insert(0, new string[] { "button1", "button2" });
SerializeToClipboard(items);
}
private const string CF_DESIGNERCOMPONENTS_V2 = "CF_DESIGNERCOMPONENTS_V2";
public static void SerializeToClipboard(ICollection collection)
{
if (collection != null && collection.Count > 0) {
var bf = new BinaryFormatter();
var mgr = new DesignerSerializationManager();
var svc = new CodeDomComponentSerializationService(mgr);
var store = svc.CreateStore();
foreach (object obj in collection) {
svc.Serialize(store, obj);
}
store.Close();
using (var ms = new MemoryStream()) {
bf.Serialize(ms, store);
byte[] bytes = ms.ToArray();
Clipboard.SetDataObject(new DataObject(CF_DESIGNERCOMPONENTS_V2, bytes), true);
}
}
}
}
}
Medjutim, ako izvrste kod i probate da pastujete rezultat na formu dobiju se dva button-a ali su oba na istoj lokaciji i imaju nazive tipa object_86d73733_af1f_425a_9bd2_17471d43333f.
Moje je pitanje: da li neko zna u cemu je problem kod serijalizacije na clipboard i kako ga resiti?