0

I have an XML-file, its structure:

<?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>

I need to load it into TreeView WPF and display from there plugins' names. I tried to do it:

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;
            }
}

But my treeview displays only classes, not names. I can't understand, how to work with treeview and XML. Here is image of my treeview with loaded XML.

Please, help me! :)

UPDATE

How can I show such example with folders and separators?

<?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>

1 Answer 1

2

Welcome to SO!

To answer your question, you should be binding your XmlDocument to the ListView's ItemsSource property like this:

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);

Then in your XAML you declare GridViewCollumns for the attributes you want to display:

<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>

Result:

enter image description here

To be honest though I would recommend against binding directly to an XmlDocument like this. XML is designed to encode documents, once you've actually loaded the data off disk there's really little to be gained by keeping it in that format and sooner or later it'll just wind up getting in the way. A better solution is to create an intermediate data-structure which you can decorate with attributes to show how the XML schema maps the data:

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; }
}

Your load code now deseralizes directly into an array of type Plugin and assigns it to your ListView's ItemsSource directly:

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[];

A slight modification to your ListView column bindings and you're done:

<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>
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for help! But I have a question: is it possible to replace ListBox with TreeView? If there are folders in XML, I need to show them in ListBox, but it does not provide with "folders", because in listbox there is only column.
I've mentioned an example in update of my question, please, check.
That's a completely differently problem and one that you should ask separately, preferably with the XML tag (there will be people there more knowledgeable about .NET implementations like this). This can certainly be done, although I'm not sure about the specific syntax you're using. If you have control of your XML files then create a data tree in code and then modify my code to write it out instead; that will show you the XML schema you should be using for serializing back in. (But like I said, a separate question will give you much better answers than this).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.