如何将特定的、反序列化的 XML 类结构绑定到 Treeview [英] How to bind specific, deserialized from XML class structure to Treeview

查看:21
本文介绍了如何将特定的、反序列化的 XML 类结构绑定到 Treeview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作将数据从我的 xml 文件反序列化为类结构的应用程序.我通过将 XML 粘贴为类"工具准备了类,但是所有内容都是在公共字段或表上制作的,当我尝试为 List 或 ObservableCollections 序列化器更改它时,停止正确加载 xml 文档.

我接下来要做的是从树视图中选择一些元素,编辑它,然后再次保存到 xml 文件.我不想直接在 .xml 上这样做.这是我的 XML 示例:

 <nagłówek><自动><nazwa>Autorzy:</nazwa><auto atr="one"><数字>222</数字><imię>Rust</imię><nazwisko>雪</nazwisko></auto><自动><数字>111</数字><imię>伊恩</imię><nazwisko>现在</nazwisko></auto></autorzy></nagłówek>...

这里是类的例子

///<备注/>[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)][System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]公开部分课程计划{私人计划Nagłówek nagłówekField;私人计划Główny głównyField;///<备注/>公共计划Nagłówek nagłówek{得到{返回 this.nagłówekField;}放{this.nagłówekField = 值;}}///<备注/>公共计划Główny główny{得到{返回 this.głównyField;}放{this.głównyField = 值;}}}///<备注/>[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]公共部分课程计划Nagłówek{私人计划NagłówekAutorzy autorzyField;///<备注/>公共计划NagłówekAutorzy autorzy{得到{返回 this.autorzyField;}放{this.autozyField = 值;}}}

以及我如何加载 xml:

//创建 XmlSerializer 的实例,指定类型和命名空间.XmlSerializer 序列化器 = new XmlSerializer(typeof(XML.plan));//需要一个 FileStream 来读取 XML 文档.FileStream fs = new FileStream("...somepath.../Untitled4.xml", FileMode.Open);XmlReader 阅读器 = XmlReader.Create(fs);//使用 Deserialize 方法恢复对象的状态.i = (XML.plan)serializer.Deserialize(reader);fs.Close();

这是我得到的加上我的 xml 文件,也许这会帮助你帮助我:).

更新 - 编辑

重新阅读您的问题,我看到您的要求是允许用户加载在树中编辑保存 XML.这比加载更复杂.以下是步骤:

首先,添加用于加载和保存 XML 的自定义路由 UI 命令:

public static class CustomCommands{public static readonly RoutedUICommand LoadXMLCommand = new RoutedUICommand("Load XML", "LoadXML", typeof(Window1));public static readonly RoutedUICommand SaveXMLCommand = new RoutedUICommand("Save XML", "SaveXML", typeof(Window1));}

接下来,在您的 Window1 类中为这些操作添加实际的 c# 逻辑:

public 部分类 Window1 : Window{公共窗口 1(){初始化组件();}私有无效 ExecutedLoadXML(对象发送者,ExecutedRoutedEventArgs e){string xml = @"<plan xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd""><nagłówek><自动><nazwa>Autorzy:</nazwa><auto atr=""one""><数字>222</数字><imię>Rust</imię><nazwisko>雪</nazwisko></auto><自动><数字>111</数字><imię>伊恩</imię><nazwisko>现在</nazwisko></auto></autorzy></nagłówek></计划>";var plan = XmlSerializationHelper.LoadFromXML(xml);var children = new List();孩子.添加(计划);treeView1.ItemsSource = null;treeView1.Items.Clear();treeView1.ItemsSource = 儿童;}私有无效 ExecutedSaveXML(对象发送者,ExecutedRoutedEventArgs e){var planList = treeView1.ItemsSource as IList;if (planList != null && planList.Count > 0){//Kludge 强制挂起的编辑更新treeView1.Focus();//替换为实际的保存代码!Debug.WriteLine(planList[0].GetXml());}}}

如您所见,我只是从硬编码字符串加载,并通过调试写行进行保存.您将需要用真正的逻辑替换这些.

接下来,在 XAML 中,将上面定义的命令添加到

然后,在 XAML 中添加带有按钮的 ToolBarTrayToolBar 以加载和保存 XML,并将按钮绑定到您添加到 CommandBindings 以上.

最后,在 XAML 中,对于每个包含数据字段的 DataTemplateHierarchicalDataTemplate,用适当的框架替换该字段的 TextBlock元素进行编辑.根据需要添加任何标签作为额外的 TextBlock,并将它们全部包装在一个容器中,例如 Grid.

这里有一些有用的东西:

<Window.CommandBindings><CommandBinding Command="w:CustomCommands.LoadXMLCommand" Executed="ExecutedLoadXML"/><CommandBinding Command="w:CustomCommands.SaveXMLCommand" Executed="ExecutedSaveXML"/></Window.CommandBindings><窗口.资源><HierarchicalDataTemplate DataType="{x:Type w:plan}" ItemsSource="{Binding Path=Items}"><TextBlock Text="计划"></TextBlock></HierarchicalDataTemplate ><HierarchicalDataTemplate DataType="{x:Type w:planNagłówek}" ItemsSource="{Binding Path=autorzy}"><TextBlock Text="Nagłówek"></TextBlock></HierarchicalDataTemplate ><HierarchicalDataTemplate DataType="{x:Type w:planNagłówekAutorzy}" ItemsSource="{Binding Path=autor}"><Grid Margin="3" MinWidth="300"><Grid.RowDefinitions><行定义/></Grid.RowDefinitions><Grid.ColumnDefinitions><列定义/><列定义/></Grid.ColumnDefinitions><TextBlock Text="nazwa:" Grid.Column="0" Grid.Row="0"/><TextBox Text="{Binding Path=nazwa, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/></网格></HierarchicalDataTemplate ><DataTemplate DataType="{x:Type w:planNagłówekAutorzyAutor}"><Border BorderBrush="Gray" BorderThickness="1" MinWidth="300"><Grid Margin="3" ><Grid.RowDefinitions><行定义/><行定义/><行定义/><行定义/></Grid.RowDefinitions><Grid.ColumnDefinitions><列定义/><列定义/></Grid.ColumnDefinitions><TextBlock Text="atr:" Grid.Column="0" Grid.Row="0"/><TextBox Text="{Binding Path=atr, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/><TextBlock Text="numer:" Grid.Column="0" Grid.Row="1"/><TextBox Text="{Binding Path=numer, Mode=TwoWay}" Grid.Column="1" Grid.Row="1"/><TextBlock Text="imię:" Grid.Column="0" Grid.Row="2"/><TextBox Text="{Binding Path=imię, Mode=TwoWay}" Grid.Column="1" Grid.Row="2"/><TextBlock Text="nazwisko:" Grid.Column="0" Grid.Row="3"/><TextBox Text="{Binding Path=nazwisko, Mode=TwoWay}" Grid.Column="1" Grid.Row="3"/></网格></边框></数据模板 ></Window.Resources><DockPanel><ToolBarTray DockPanel.Dock="Top"><工具栏><Button Command="w:CustomCommands.LoadXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/><Button Command="w:CustomCommands.SaveXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/></工具栏></ToolBarTray><Grid DockPanel.Dock="底部"><TreeView Margin="3" Name="treeView1"><TreeView.ItemContainerStyle><Style TargetType="{x:Type TreeViewItem}"><Setter Property="IsExpanded" Value="True"/></风格></TreeView.ItemContainerStyle></树视图></网格></DockPanel></窗口>

它生成的用户界面如下所示:

我不是 UI 设计师,所以你会想要玩这个以获得更漂亮的东西.

更新 2

GetXML() 扩展方法:

公共静态类 XmlSerializationHelper{公共静态字符串 GetXml(T obj,XmlSerializer 序列化程序,bool omitStandardNamespaces){使用 (var textWriter = new StringWriter()){XmlWriterSettings settings = new XmlWriterSettings();settings.Indent = true;//用于装饰目的.settings.IndentChars = " ";//用于装饰目的.使用 (var xmlWriter = XmlWriter.Create(textWriter, settings)){如果(省略标准命名空间){XmlSerializerNamespaces ns = new XmlSerializerNamespaces();ns.Add("", "");//禁用 xmlns:xsi 和 xmlns:xsd 行.serializer.Serialize(xmlWriter, obj, ns);}别的{serializer.Serialize(xmlWriter, obj);}}返回 textWriter.ToString();}}public static string GetXml(this T obj, bool omitNamespace){XmlSerializer 序列化器 = new XmlSerializer(obj.GetType());返回 GetXml(obj, serializer, omitNamespace);}public static string GetXml(this T obj){返回 GetXml(obj, false);}public static T LoadFromXML(这个字符串xmlString){返回 xmlString.LoadFromXML(new XmlSerializer(typeof(T)));}public static T LoadFromXML(这个字符串 xmlString,XmlSerializer 序列号){T returnValue = default(T);使用 (StringReader reader = new StringReader(xmlString)){对象结果 = serial.Deserialize(reader);如果(结果是 T){returnValue = (T)result;}}返回返回值;}public static T LoadFromFile(字符串文件名){XmlSerializer serial = new XmlSerializer(typeof(T));尝试{使用 (var fs = new FileStream(filename, FileMode.Open)){对象结果 = serial.Deserialize(fs);如果(结果是 T){返回 (T) 结果;}}}捕获(异常前){Debug.WriteLine(ex.ToString());扔;}返回默认值(T);}}

I want to make app which deserialized data from my xml file to class structure. I prepared classes by 'Paste XML as classes' tool, however everything is made on common fields or tables and when I tried to change it for List or ObservableCollections serializator stopped load xml document properly.

What i want to do next is possibilty to choose from treeview for instance some element, edit it, and save to xml file again. I don't want to do that on .xml directly. this is a sample of my XML:

    <plan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">
<nagłówek>
<autorzy>
<nazwa>Autorzy:</nazwa>
<autor atr="one">
<numer>222</numer>
<imię>Rust</imię>
<nazwisko>Snow</nazwisko>
</autor>

<autor>
<numer>111</numer>
<imię>Ian</imię>
<nazwisko>Nower</nazwisko>
</autor>
</autorzy>
</nagłówek>
...

Here are exemple of classes

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class plan
{

    private planNagłówek nagłówekField;

    private planGłówny głównyField;

    /// <remarks/>
    public planNagłówek nagłówek
    {
        get
        {
            return this.nagłówekField;
        }
        set
        {
            this.nagłówekField = value;
        }
    }

    /// <remarks/>
    public planGłówny główny
    {
        get
        {
            return this.głównyField;
        }
        set
        {
            this.głównyField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class planNagłówek 
{

    private planNagłówekAutorzy autorzyField;

    /// <remarks/>
    public planNagłówekAutorzy autorzy
    {
        get
        {
            return this.autorzyField;
        }
        set
        {
            this.autorzyField = value;
        }
    }
}

and how i load xml:

// Create an instance of the XmlSerializer specifying type and namespace.
            XmlSerializer serializer = new XmlSerializer(typeof(XML.plan));
            // A FileStream is needed to read the XML document.
            FileStream fs = new FileStream("...somepath.../Untitled4.xml", FileMode.Open);
            XmlReader reader = XmlReader.Create(fs);

            // Use the Deserialize method to restore the object's state.
            i = (XML.plan)serializer.Deserialize(reader);
            fs.Close();    

Here is what I've got plus my xml file, maybe this will help you help me:) https://drive.google.com/file/d/0B0wPodV30rnJSVA1ckVxWldDRDA/view

解决方案

To display a hierarchy of classes in a WPF TreeView, in XAML you need to define a HierarchicalDataTemplate corresponding to each type of class in your hierarchy that might have children, and a DataTemplate corresponding to each type of class in your hierarchy that will not have children. Each data template should define a single framework element (TextBlock, for instance, or a container control such as a DockPanel with any number of embedded framework elements as children) that will display the data of that type of class in the tree, with appropriate bindings.

First, auto-generate classes for your XML using xsd.exe. To simply display the data in the tree you do not need to implement INotifyPropertyChanged or use an ObservableCollection<T> for children:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class plan
{

    private planNagłówek[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("nagłówek", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public planNagłówek[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class planNagłówek
{

    private planNagłówekAutorzy[] autorzyField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("autorzy", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public planNagłówekAutorzy[] autorzy
    {
        get
        {
            return this.autorzyField;
        }
        set
        {
            this.autorzyField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class planNagłówekAutorzy
{

    private string nazwaField;

    private planNagłówekAutorzyAutor[] autorField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string nazwa
    {
        get
        {
            return this.nazwaField;
        }
        set
        {
            this.nazwaField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("autor", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public planNagłówekAutorzyAutor[] autor
    {
        get
        {
            return this.autorField;
        }
        set
        {
            this.autorField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class planNagłówekAutorzyAutor
{

    private string numerField;

    private string imięField;

    private string nazwiskoField;

    private string atrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string numer
    {
        get
        {
            return this.numerField;
        }
        set
        {
            this.numerField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string imię
    {
        get
        {
            return this.imięField;
        }
        set
        {
            this.imięField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string nazwisko
    {
        get
        {
            return this.nazwiskoField;
        }
        set
        {
            this.nazwiskoField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string atr
    {
        get
        {
            return this.atrField;
        }
        set
        {
            this.atrField = value;
        }
    }
}

Next, define a user interface in XAML in which to display these classes, manually creating appropriate data templates for each level:

<Window x:Class="WpfTreeViewNew.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:w="clr-namespace:WpfTreeViewNew"
    Title="Window1" Height="300" Width="600">
    <Window.Resources>
        <HierarchicalDataTemplate  DataType="{x:Type w:plan}" ItemsSource="{Binding Path=Items}">
            <TextBlock Text="Plan">
            </TextBlock>
        </HierarchicalDataTemplate >
        <HierarchicalDataTemplate  DataType="{x:Type w:planNagłówek}" ItemsSource="{Binding Path=autorzy}">
            <TextBlock Text="Nagłówek">
            </TextBlock>
        </HierarchicalDataTemplate >
        <HierarchicalDataTemplate  DataType="{x:Type w:planNagłówekAutorzy}" ItemsSource="{Binding Path=autor}">
            <TextBlock Text="{Binding Path=nazwa}"/>
        </HierarchicalDataTemplate >
        <DataTemplate  DataType="{x:Type w:planNagłówekAutorzyAutor}">
            <Border BorderBrush="Gray" BorderThickness="1" MinWidth="300">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="3" Text="{Binding Path=atr}"/>
                    <TextBlock Margin="3" Text="{Binding Path=numer}"/>
                    <TextBlock Margin="3" Text="{Binding Path=imię}"/>
                    <TextBlock Margin="3" Text="{Binding Path=nazwisko}"/>
                </StackPanel>
            </Border>
        </DataTemplate >
    </Window.Resources>
        <Grid DockPanel.Dock="Bottom">
            <TreeView Margin="3" Name="treeView1">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True" />
                    </Style>
                </TreeView.ItemContainerStyle>
            </TreeView>
        </Grid>
</Window>

Finally, load the data programmatically, for instance on startup:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        string xml = @"<plan xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd"">
  <nagłówek>
    <autorzy>
      <nazwa>Autorzy:</nazwa>
      <autor atr=""one"">
        <numer>222</numer>
        <imię>Rust</imię>
        <nazwisko>Snow</nazwisko>
      </autor>

      <autor>
        <numer>111</numer>
        <imię>Ian</imię>
        <nazwisko>Nower</nazwisko>
      </autor>
    </autorzy>
  </nagłówek>
</plan>
";
        var plan = XmlSerializationHelper.LoadFromXML<plan>(xml);
        var xml2 = plan.GetXml();
        Debug.WriteLine(xml2); // For testing

        var children = new List<plan>();
        children.Add(plan);

        treeView1.Items.Clear();
        treeView1.ItemsSource = children;
    }
}

This produces something that looks like the following:

You will want to replace each template with something more beautiful.

Honestly, after grinding all this out I now believe the WinForms tree may be easier to work with.

Update - Editing

Re-reading your question, I see your requirement is to allow the user to load, edit in tree, and save the XML. This is more complicated than just loading. Here are the steps:

First, add custom routed UI commands for loading and saving XML:

public static class CustomCommands
{
    public static readonly RoutedUICommand LoadXMLCommand = new RoutedUICommand("Load XML", "LoadXML", typeof(Window1));

    public static readonly RoutedUICommand SaveXMLCommand = new RoutedUICommand("Save XML", "SaveXML", typeof(Window1));
}

Next, add the actual c# logic in your Window1 class for these actions:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void ExecutedLoadXML(object sender, ExecutedRoutedEventArgs e)
    {
        string xml = @"<plan xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd"">
  <nagłówek>
    <autorzy>
      <nazwa>Autorzy:</nazwa>
      <autor atr=""one"">
        <numer>222</numer>
        <imię>Rust</imię>
        <nazwisko>Snow</nazwisko>
      </autor>

      <autor>
        <numer>111</numer>
        <imię>Ian</imię>
        <nazwisko>Nower</nazwisko>
      </autor>
    </autorzy>
  </nagłówek>
</plan>
";
        var plan = XmlSerializationHelper.LoadFromXML<plan>(xml);

        var children = new List<plan>();
        children.Add(plan);

        treeView1.ItemsSource = null;
        treeView1.Items.Clear();
        treeView1.ItemsSource = children;
    }

    private void ExecutedSaveXML(object sender, ExecutedRoutedEventArgs e)
    {
        var planList = treeView1.ItemsSource as IList<plan>;
        if (planList != null && planList.Count > 0)
        {
            // Kludge to force pending edits to update
            treeView1.Focus();
            // Replace with actual save code!
            Debug.WriteLine(planList[0].GetXml());
        }
    }
}

As you can see I'm just loading from a hardcoded string, and saving by doing a debug writeline. You will want to replace these with the real logic.

Next, in XAML, add the commands defined above to <Window.CommandBindings>

Then, in XAML add a ToolBarTray and ToolBar with buttons to load and save XML, and bind the buttons to the commands you added to the CommandBindings above.

Finally, in XAML, for each DataTemplate or HierarchicalDataTemplate that contains a data field, replace the TextBlock for that field with an appropriate framework element for editing. Add any labels as desired as additional TextBlocks, and wrap them all up in a container such as a Grid.

Here is something that works:

<Window x:Class="WpfTreeViewNew.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:w="clr-namespace:WpfTreeViewNew"
    Title="Window1" Height="300" Width="600">
    <Window.CommandBindings>
        <CommandBinding Command="w:CustomCommands.LoadXMLCommand" Executed="ExecutedLoadXML"/>
        <CommandBinding Command="w:CustomCommands.SaveXMLCommand" Executed="ExecutedSaveXML"/>
    </Window.CommandBindings>
    <Window.Resources>
        <HierarchicalDataTemplate  DataType="{x:Type w:plan}" ItemsSource="{Binding Path=Items}">
            <TextBlock Text="Plan">
            </TextBlock>
        </HierarchicalDataTemplate >
        <HierarchicalDataTemplate  DataType="{x:Type w:planNagłówek}" ItemsSource="{Binding Path=autorzy}">
            <TextBlock Text="Nagłówek">
            </TextBlock>
        </HierarchicalDataTemplate >
        <HierarchicalDataTemplate  DataType="{x:Type w:planNagłówekAutorzy}" ItemsSource="{Binding Path=autor}">
            <Grid Margin="3" MinWidth="300">
                <Grid.RowDefinitions>
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock Text="nazwa:" Grid.Column="0" Grid.Row="0"/>
                <TextBox Text="{Binding Path=nazwa, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/>
            </Grid>
        </HierarchicalDataTemplate >
        <DataTemplate  DataType="{x:Type w:planNagłówekAutorzyAutor}">
            <Border BorderBrush="Gray" BorderThickness="1" MinWidth="300">
                <Grid Margin="3" >
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="atr:" Grid.Column="0" Grid.Row="0"/>
                    <TextBox Text="{Binding Path=atr, Mode=TwoWay}" Grid.Column="1" Grid.Row="0"/>
                    <TextBlock Text="numer:" Grid.Column="0" Grid.Row="1"/>
                    <TextBox Text="{Binding Path=numer, Mode=TwoWay}" Grid.Column="1" Grid.Row="1"/>
                    <TextBlock Text="imię:" Grid.Column="0" Grid.Row="2"/>
                    <TextBox Text="{Binding Path=imię, Mode=TwoWay}" Grid.Column="1" Grid.Row="2"/>
                    <TextBlock Text="nazwisko:" Grid.Column="0" Grid.Row="3"/>
                    <TextBox Text="{Binding Path=nazwisko, Mode=TwoWay}" Grid.Column="1" Grid.Row="3"/>
                </Grid>
            </Border>
        </DataTemplate >
    </Window.Resources>
    <DockPanel>
        <ToolBarTray DockPanel.Dock="Top">
            <ToolBar>
                <Button Command="w:CustomCommands.LoadXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/>
                <Button Command="w:CustomCommands.SaveXMLCommand" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"/>
            </ToolBar>
        </ToolBarTray>
        <Grid DockPanel.Dock="Bottom">
            <TreeView Margin="3" Name="treeView1">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True" />
                    </Style>
                </TreeView.ItemContainerStyle>
            </TreeView>
        </Grid>
    </DockPanel>
</Window>

And the UI it produces looks like:

I'm not a UI designer so you'll want to play with this to get something more beautiful.

Update 2

GetXML() extension method:

public static class XmlSerializationHelper
{
    public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
    {
        using (var textWriter = new StringWriter())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;        // For cosmetic purposes.
            settings.IndentChars = "    "; // For cosmetic purposes.
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
            {
                if (omitStandardNamespaces)
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
                    serializer.Serialize(xmlWriter, obj, ns);
                }
                else
                {
                    serializer.Serialize(xmlWriter, obj);
                }
            }
            return textWriter.ToString();
        }
    }

    public static string GetXml<T>(this T obj, bool omitNamespace)
    {
        XmlSerializer serializer = new XmlSerializer(obj.GetType());
        return GetXml(obj, serializer, omitNamespace);
    }

    public static string GetXml<T>(this T obj)
    {
        return GetXml(obj, false);
    }

    public static T LoadFromXML<T>(this string xmlString)
    {
        return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
    }

    public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
    {
        T returnValue = default(T);

        using (StringReader reader = new StringReader(xmlString))
        {
            object result = serial.Deserialize(reader);
            if (result is T)
            {
                returnValue = (T)result;
            }
        }
        return returnValue;
    }

    public static T LoadFromFile<T>(string filename)
    {
        XmlSerializer serial = new XmlSerializer(typeof(T));
        try
        {
            using (var fs = new FileStream(filename, FileMode.Open))
            {
                object result = serial.Deserialize(fs);
                if (result is T)
                {
                    return (T)result;
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
            throw;
        }
        return default(T);
    }
}

这篇关于如何将特定的、反序列化的 XML 类结构绑定到 Treeview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆