Alex Rivera | Logout

How can you clone a WPF object?

Asked 2008-08-28T15:14:29.967
43

Anybody have a good example how to deep clone a WPF object, preserving databindings?


The marked answer is the first part.

The second part is that you have to create an ExpressionConverter and inject it into the serialization process. Details for this are here:
http://www.codeproject.com/KB/WPF/xamlwriterandbinding.aspx?fid=1428301&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2801571

Edit
Report

1 Answer

6

There are some great answers here. Very helpful. I had tried various approaches for copying Binding information, including the approach outlined in http://pjlcon.wordpress.com/2011/01/14/change-a-wpf-binding-from-sync-to-async-programatically/ but the information here is the best on the Internet!

I created a re-usable extension method for dealing with InvalidOperationException “Binding cannot be changed after it has been used.” In my scenario, I was maintaining some code somebody wrote, and after a major DevExpress DXGrid framework upgrade, it no longer worked. The following solved my problem perfectly. The part of the code where I return the object could be nicer, and I will re-factor that later.

/// <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.");
        }

      
answered 2013-02-06T22:54:28.953

Your Answer