繁体   English   中英

C# 序列化 UIElementCollection

[英]C# serialization UIElementCollection

我有一些代码:

    public static UIElementCollection DeSerializeXAML(string filename)
    {
        // Load XAML from file. Use 'using' so objects are disposed of properly.
        using (System.IO.FileStream fs = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {
            return System.Windows.Markup.XamlReader.Load(fs) as UIElementCollection; //EXCEPTION
        }
    }

    // Serializes any UIElement object to XAML using a given filename.
    public static void SerializeToXAML(UIElementCollection elements, string filename)
    {
        // Use XamlWriter object to serialize element
        string strXAML = System.Windows.Markup.XamlWriter.Save(elements);

        // Write XAML to file. Use 'using' so objects are disposed of properly.
        using (System.IO.FileStream fs = System.IO.File.Create(filename))
        {
            using (System.IO.StreamWriter streamwriter = new System.IO.StreamWriter(fs))
            {
                streamwriter.Write(strXAML);
            }
        }
    }

    private void btnSave_Click(object sender, RoutedEventArgs e)
    {
        SaveFileDialog dlg = new SaveFileDialog();
        dlg.FileName = "UIElement File"; // Default file name
        dlg.DefaultExt = ".xaml"; // Default file extension
        dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension

        // Show save file dialog box
        Nullable<bool> result = dlg.ShowDialog();

        // Process save file dialog box results
        if (result == true)
        {
            // Save document
            string filename = dlg.FileName;
            SerializeToXAML(myCanvas.Children, filename);
        }
    }

    private void btnLoad_Click(object sender, RoutedEventArgs e)
    {
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        dlg.DefaultExt = ".xaml"; // Default file extension
        dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension

        // Show open file dialog box
        Nullable<bool> result = dlg.ShowDialog();

        // Process open file dialog box results
        if (result == true)
        {
            string filename = dlg.FileName;
            UIElementCollection elements = DeSerializeXAML(filename) as UIElementCollection;

            // Add all child elements (lines, rectangles etc) to canvas
            myCanvas.Children.Clear();
            foreach (UIElement el in elements)
            {
                myCanvas.Children.Add(el);
            }
        }
    }

这适用于序列化,但是当您反序列化时,会引发异常。

异常文本(用谷歌翻译):“您没有找到适合该类型的构造函数”System.Windows.Controls.UIElementCollection。

“您可以使用 Arguments 或 FactoryMethod 指令来生成此类型。”:行号“1”和行“22”中的位置。

UIElementCollection实例绑定到特定的Visual ,因此,它不适合序列化(正如@kostya-k 指出的那样)。 反序列化逻辑不知道如何创建新的UIElementCollection因为它不知道将它与哪个Visual关联。 无论如何,创建一个新集合是没有意义的,因为您只是将值转移到myCanvas.Children

好消息是您可以使用XamlObjectWriter直接填充myCanvas.Children而不是实例化新集合:

public static void DeSerializeXAML(UIElementCollection elements, string filename)
{
    var context = System.Windows.Markup.XamlReader.GetWpfSchemaContext();

    var settings = new System.Xaml.XamlObjectWriterSettings
                       {
                           RootObjectInstance = elements
                       };

    using (var reader = new System.Xaml.XamlXmlReader(filename))
    using (var writer = new System.Xaml.XamlObjectWriter(context, settings))
    {
        System.Xaml.XamlServices.Transform(reader, writer);
    }
}

private void btnLoad_Click(object sender, RoutedEventArgs e)
{
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
    dlg.DefaultExt = ".xaml"; // Default file extension
    dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension

    // Show open file dialog box
    Nullable<bool> result = dlg.ShowDialog();

    // Process open file dialog box results
    if (result == true)
    {
        string filename = dlg.FileName;
        myCanvas.Children.Clear();
        DeSerializeXAML(myCanvas.Children, filename);
    }
}

UIElementCollection不用于序列化。 它意味着在构建 WPF 可视化树时使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM