如何将 XML 加载到 C# WPF 树视图中
How to load XML into C# WPF treeview
我有一个 XML 文件,其结构:
<?xml version="1.0" encoding="UTF-8"?>
<PluginMenuLayout DocSchema="1" Name="PluginList">
<Plugin CLSID="{141AC902-4256-4332-4252-455645527E31}" CLSIDMD5="{7286134B-6592-8EE7-6BE8-60A5EC833C10}" Category="1" Name="BREVERB 2 Cakewalk" OriginalName="BREVERB 2 Cakewalk"/>
<Plugin CLSID="{56535454-482D-3374-6833-000000000000}" Category="9" Name="TH3" OriginalName="TH3"/>
<Plugin CLSID="{141AC902-4357-626C-424F-4F5354317E31}" CLSIDMD5="{BB2041A0-618D-98FE-6F9B-F22F6E1A2520}" Category="1" Name="Boost11ртпктеутуетет" OriginalName="Boost11ртпктеутуетет"/>
<Plugin CLSID="{5653544D-6C70-676D-656C-6F64796E6520}" Category="9" Name="Melodyne" OriginalName="Melodyne"/></PluginMenuLayout>
我需要将它加载到 TreeView WPF 中并从那里显示插件名称。我试过了:
private void func(){
DataContext = this;
TheXML = XDocument.Load(@"C:\Users\Anton\Desktop\plglst.xml");
myTreeView.DataContext = TheXML;
myTreeView.UpdateLayout();
}
private XDocument _theXML;
public XDocument TheXML
{
get => _theXML;
set => _theXML = value;
}
}
但我的树视图只显示 类,不显示名称。我无法理解如何使用 treeview 和 XML。 Here is image of my treeview with loaded XML.
请帮帮我! :)
更新
如何显示带有文件夹和分隔符的示例?
<?xml version="1.0" encoding="UTF-8"?>
<PluginMenuLayout DocSchema="1" Name="newlist">
<Plugin CLSID="{141AC902-4256-4332-4252-455645527E31}" CLSIDMD5="{7286134B-6592-8EE7-6BE8-60A5EC833C10}" Category="1" Name="BREVERB 2 Cakewalk" OriginalName="BREVERB 2 Cakewalk"/>
<Plugin CLSID="{5653544D-6C70-676D-656C-6F64796E6520}" Category="9" Name="Melodyne" OriginalName="Melodyne"/><Plugin CLSID="{56535454-482D-3374-6833-000000000000}" Category="9" Name="TH3" OriginalName="TH3"/>
<Folder Name="Okay">
<Plugin CLSID="{54DE473B-D405-4F77-A19A-995FDC7E374E}" Category="2" Name="Cakewalk TTS-1" OriginalName="Cakewalk TTS-1"/>
<Plugin CLSID="{F718845E-BC87-4248-83C4-A9C99294EA63}" Category="2" Name="GroovePlayer" OriginalName="GroovePlayer"/>
<Separator/>
<Plugin CLSID="{141AC902-4550-4E4F-5349-2D454C457E31}" CLSIDMD5="{9A2FD0E5-C1C5-2926-3FA0-8B45DBEDA75C}" Category="3" Name="SI-Electric Piano" OriginalName="SI-Electric Piano"/>
<Plugin CLSID="{141AC902-5354-5247-5349-2D5354527E31}" CLSIDMD5="{0D9CD314-8203-ACA3-F1BA-7896F2C3BCD7}" Category="3" Name="SI-String Section" OriginalName="SI-String Section"/>
</Folder>
</PluginMenuLayout>
欢迎来到 SO!
要回答您的问题,您应该像这样将 XmlDocument 绑定到 ListView 的 ItemsSource 属性:
XmlDocument d = new XmlDocument();
d.Load(@"C:\Users\Anton\Desktop\plglst.xml");
var binding = new Binding();
binding.Source = d.DocumentElement;
theListView.SetBinding(ListView.ItemsSourceProperty, binding);
然后在 XAML 中为要显示的属性声明 GridViewCollumns:
<ListView x:Name="theListView">
<ListView.View>
<GridView>
<GridViewColumn Header="CLSID" DisplayMemberBinding="{Binding XPath=@CLSID}"/>
<GridViewColumn Header="Category" DisplayMemberBinding="{Binding XPath=@Category}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=@Name}"/>
<GridViewColumn Header="Original Name" DisplayMemberBinding="{Binding XPath=@OriginalName}"/>
</GridView>
</ListView.View>
</ListView>
结果:
老实说,尽管我建议不要像这样直接绑定到 XmlDocument。 XML 旨在对文档进行编码,一旦您实际从磁盘加载数据,将其保留为该格式几乎无济于事,迟早会成为阻碍。更好的解决方案是创建一个中间 data-structure,您可以用属性装饰它以显示 XML 模式如何映射数据:
public class Plugin
{
[XmlAttribute("CLSID")]
public string CLSID { get; set; }
[XmlAttribute("Category")]
public string Category { get; set; }
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlAttribute("OriginalName")]
public string OriginalName { get; set; }
}
您的加载代码现在直接反序列化为 Plugin
类型的数组,并将其直接分配给您的 ListView 的 ItemsSource:
var serializer = new XmlSerializer(typeof(Plugin[]), new XmlRootAttribute { ElementName = "PluginMenuLayout" });
using (XmlReader reader = XmlReader.Create(@"C:\Users\Anton\Desktop\plglst.xml"))
theListView.ItemsSource = serializer.Deserialize(reader) as Plugin[];
对您的 ListView 列绑定稍作修改即可完成:
<ListView x:Name="theListView">
<ListView.View>
<GridView>
<GridViewColumn Header="CLSID" DisplayMemberBinding="{Binding CLSID}"/>
<GridViewColumn Header="Category" DisplayMemberBinding="{Binding Category}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Original Name" DisplayMemberBinding="{Binding OriginalName}"/>
</GridView>
</ListView.View>
</ListView>
我有一个 XML 文件,其结构:
<?xml version="1.0" encoding="UTF-8"?>
<PluginMenuLayout DocSchema="1" Name="PluginList">
<Plugin CLSID="{141AC902-4256-4332-4252-455645527E31}" CLSIDMD5="{7286134B-6592-8EE7-6BE8-60A5EC833C10}" Category="1" Name="BREVERB 2 Cakewalk" OriginalName="BREVERB 2 Cakewalk"/>
<Plugin CLSID="{56535454-482D-3374-6833-000000000000}" Category="9" Name="TH3" OriginalName="TH3"/>
<Plugin CLSID="{141AC902-4357-626C-424F-4F5354317E31}" CLSIDMD5="{BB2041A0-618D-98FE-6F9B-F22F6E1A2520}" Category="1" Name="Boost11ртпктеутуетет" OriginalName="Boost11ртпктеутуетет"/>
<Plugin CLSID="{5653544D-6C70-676D-656C-6F64796E6520}" Category="9" Name="Melodyne" OriginalName="Melodyne"/></PluginMenuLayout>
我需要将它加载到 TreeView WPF 中并从那里显示插件名称。我试过了:
private void func(){
DataContext = this;
TheXML = XDocument.Load(@"C:\Users\Anton\Desktop\plglst.xml");
myTreeView.DataContext = TheXML;
myTreeView.UpdateLayout();
}
private XDocument _theXML;
public XDocument TheXML
{
get => _theXML;
set => _theXML = value;
}
}
但我的树视图只显示 类,不显示名称。我无法理解如何使用 treeview 和 XML。 Here is image of my treeview with loaded XML.
请帮帮我! :)
更新
如何显示带有文件夹和分隔符的示例?
<?xml version="1.0" encoding="UTF-8"?>
<PluginMenuLayout DocSchema="1" Name="newlist">
<Plugin CLSID="{141AC902-4256-4332-4252-455645527E31}" CLSIDMD5="{7286134B-6592-8EE7-6BE8-60A5EC833C10}" Category="1" Name="BREVERB 2 Cakewalk" OriginalName="BREVERB 2 Cakewalk"/>
<Plugin CLSID="{5653544D-6C70-676D-656C-6F64796E6520}" Category="9" Name="Melodyne" OriginalName="Melodyne"/><Plugin CLSID="{56535454-482D-3374-6833-000000000000}" Category="9" Name="TH3" OriginalName="TH3"/>
<Folder Name="Okay">
<Plugin CLSID="{54DE473B-D405-4F77-A19A-995FDC7E374E}" Category="2" Name="Cakewalk TTS-1" OriginalName="Cakewalk TTS-1"/>
<Plugin CLSID="{F718845E-BC87-4248-83C4-A9C99294EA63}" Category="2" Name="GroovePlayer" OriginalName="GroovePlayer"/>
<Separator/>
<Plugin CLSID="{141AC902-4550-4E4F-5349-2D454C457E31}" CLSIDMD5="{9A2FD0E5-C1C5-2926-3FA0-8B45DBEDA75C}" Category="3" Name="SI-Electric Piano" OriginalName="SI-Electric Piano"/>
<Plugin CLSID="{141AC902-5354-5247-5349-2D5354527E31}" CLSIDMD5="{0D9CD314-8203-ACA3-F1BA-7896F2C3BCD7}" Category="3" Name="SI-String Section" OriginalName="SI-String Section"/>
</Folder>
</PluginMenuLayout>
欢迎来到 SO!
要回答您的问题,您应该像这样将 XmlDocument 绑定到 ListView 的 ItemsSource 属性:
XmlDocument d = new XmlDocument();
d.Load(@"C:\Users\Anton\Desktop\plglst.xml");
var binding = new Binding();
binding.Source = d.DocumentElement;
theListView.SetBinding(ListView.ItemsSourceProperty, binding);
然后在 XAML 中为要显示的属性声明 GridViewCollumns:
<ListView x:Name="theListView">
<ListView.View>
<GridView>
<GridViewColumn Header="CLSID" DisplayMemberBinding="{Binding XPath=@CLSID}"/>
<GridViewColumn Header="Category" DisplayMemberBinding="{Binding XPath=@Category}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=@Name}"/>
<GridViewColumn Header="Original Name" DisplayMemberBinding="{Binding XPath=@OriginalName}"/>
</GridView>
</ListView.View>
</ListView>
结果:
老实说,尽管我建议不要像这样直接绑定到 XmlDocument。 XML 旨在对文档进行编码,一旦您实际从磁盘加载数据,将其保留为该格式几乎无济于事,迟早会成为阻碍。更好的解决方案是创建一个中间 data-structure,您可以用属性装饰它以显示 XML 模式如何映射数据:
public class Plugin
{
[XmlAttribute("CLSID")]
public string CLSID { get; set; }
[XmlAttribute("Category")]
public string Category { get; set; }
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlAttribute("OriginalName")]
public string OriginalName { get; set; }
}
您的加载代码现在直接反序列化为 Plugin
类型的数组,并将其直接分配给您的 ListView 的 ItemsSource:
var serializer = new XmlSerializer(typeof(Plugin[]), new XmlRootAttribute { ElementName = "PluginMenuLayout" });
using (XmlReader reader = XmlReader.Create(@"C:\Users\Anton\Desktop\plglst.xml"))
theListView.ItemsSource = serializer.Deserialize(reader) as Plugin[];
对您的 ListView 列绑定稍作修改即可完成:
<ListView x:Name="theListView">
<ListView.View>
<GridView>
<GridViewColumn Header="CLSID" DisplayMemberBinding="{Binding CLSID}"/>
<GridViewColumn Header="Category" DisplayMemberBinding="{Binding Category}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Original Name" DisplayMemberBinding="{Binding OriginalName}"/>
</GridView>
</ListView.View>
</ListView>