你怎么克隆一个WPF对象?

任何人都有一个很好的例子,如何深入克隆一个WPF对象,保持数据绑定?


标记的答案是第一部分。

第二部分是您必须创build一个ExpressionConverter并将其注入到序列化过程中。 这里的细节在这里:
http://www.codeproject.com/KB/WPF/xamlwriterandbinding.aspx?fid=1428301&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2801571

最简单的方法是使用XamlWriter将WPF对象保存为string。 Save方法会将对象及其所有子对象序列化到逻辑树中。 现在你可以创build一个新的对象并用XamlReader加载它。

例如:将对象写入xaml(假设对象是一个Grid控件):

string gridXaml = XamlWriter.Save(myGrid); 

加载到一个新的对象:

 StringReader stringReader = new StringReader(gridXaml); XmlReader xmlReader = XmlReader.Create(stringReader); Grid newGrid = (Grid)XamlReader.Load(xmlReader); 

在.NET 4.0中,新的xaml序列化堆栈使得这个更容易。

 var sb = new StringBuilder(); var writer = XmlWriter.Create(sb, new XmlWriterSettings { Indent = true, ConformanceLevel = ConformanceLevel.Fragment, OmitXmlDeclaration = true, NamespaceHandling = NamespaceHandling.OmitDuplicates, }); var mgr = new XamlDesignerSerializationManager(writer); // HERE BE MAGIC!!! mgr.XamlWriterMode = XamlWriterMode.Expression; // THERE WERE MAGIC!!! System.Windows.Markup.XamlWriter.Save(this, mgr); return sb.ToString(); 

这里有一些很好的答案。 很有帮助。 我曾尝试过各种方法来复制绑定信息,包括http://pjlcon.wordpress.com/2011/01/14/change-a-wpf-binding-from-sync-to-async-programatically/中列出的方法,但这里的信息是互联网上最好的!;

我创build了一个可重用的扩展方法来处理InvalidOperationException“绑定在使用后无法更改”。在我的场景中,我保留了一些有人写的代码,在DevExpress DXGrid框架升级之后,它不再有效。 以下解决我的问题完美。 我返回对象的代码部分可能会更好,我将在稍后重新考虑。

 /// <summary> /// Extension methods for the WPF Binding class. /// </summary> public static class BindingExtensions { public static BindingBase CloneViaXamlSerialization(this BindingBase binding) { var sb = new StringBuilder(); var writer = XmlWriter.Create(sb, new XmlWriterSettings { Indent = true, ConformanceLevel = ConformanceLevel.Fragment, OmitXmlDeclaration = true, NamespaceHandling = NamespaceHandling.OmitDuplicates, }); var mgr = new XamlDesignerSerializationManager(writer); // HERE BE MAGIC!!! mgr.XamlWriterMode = XamlWriterMode.Expression; // THERE WERE MAGIC!!! System.Windows.Markup.XamlWriter.Save(binding, mgr); StringReader stringReader = new StringReader(sb.ToString()); XmlReader xmlReader = XmlReader.Create(stringReader); object newBinding = (object)XamlReader.Load(xmlReader); if (newBinding == null) { throw new ArgumentNullException("Binding could not be cloned via Xaml Serialization Stack."); } if (newBinding is Binding) { return (Binding)newBinding; } else if (newBinding is MultiBinding) { return (MultiBinding)newBinding; } else if (newBinding is PriorityBinding) { return (PriorityBinding)newBinding; } else { throw new InvalidOperationException("Binding could not be cast."); } } } 

怎么样:

  public static T DeepClone<T>(T from) { using (MemoryStream s = new MemoryStream()) { BinaryFormatter f = new BinaryFormatter(); f.Serialize(s, from); s.Position = 0; object clone = f.Deserialize(s); return (T)clone; } } 

当然,这个深度克隆任何对象,它可能不是在城里最快的解决scheme,但它有最less的维护… 🙂