سؤال

هل لدى أي شخص مثال جيد لكيفية الاستنساخ العميق لكائن 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 (لنفترض أن الكائن كان عنصر تحكم في الشبكة):

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/ لكن المعلومات الواردة هنا هي الأفضل على الإنترنت!

لقد قمت بإنشاء طريقة تمديد قابلة للاستخدام للتعامل مع 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;
        }
    }

بالطبع هذا يستنسخ أي جسم بشكل عميق، وقد لا يكون الحل الأسرع في المدينة، ولكنه يتمتع بأقل قدر من الصيانة...:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top