任何人都有一个很好的示例,该示例如何深度克隆WPF对象并保留数据绑定?
标记的答案是第一部分。
第二部分是您必须创建一个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对象另存为字符串。 Save方法将序列化对象及其逻辑树中的所有子对象。现在,您可以创建一个新对象,并使用XamlReader加载它。
例如:
将对象写入xaml(假设该对象是Grid控件):
1
| string gridXaml = XamlWriter.Save(myGrid); |
将其加载到新对象中:
1 2 3
| StringReader stringReader = new StringReader(gridXaml);
XmlReader xmlReader = XmlReader.Create(stringReader);
Grid newGrid = (Grid)XamlReader.Load(xmlReader); |
在.NET 4.0中,新的xaml序列化堆栈使此MUCH更容易。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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/中概述的方法,但是这里的信息是Internet上最好的!
我创建了一个可重用的扩展方法来处理InvalidOperationException"绑定在使用后无法更改。"在我的场景中,我维护着某些人编写的代码,并且在主要的DevExpress DXGrid框架升级之后,它不再起作用。以下完美解决了我的问题。我返回对象的代码部分可能会更好,稍后我将对其进行重构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| /// <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.");
}
}
} |
怎么样:
1 2 3 4 5 6 7 8 9 10 11 12
| 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;
}
} |
当然,这种深度克隆会克隆任何对象,它可能不是镇上最快的解决方案,但维护最少。