如何使用WPF从XML文件创建treeview?

时间:2021-07-16 09:54:45

This is XML file

这是XML文件

 <Root>
 <RootNode name="CurrentDbName" value="DeltaTest Backup" DesiPath="E:\BuildBackups">
 <ChildNode name="Application" value="App">
  <LeafNode name="Source" value="Source" SourcePath="E:\Alertv2" /> 
  <LeafNode name="Publish" value="Publish" SourcePath="C:\Alert_Source" /> 
  </ChildNode>
 <ChildNode name="Database" value="DB">
  <LeafNode name="Dev" value="Dev" SourcePath="C:\Kiran3" /> 
  <LeafNode name="Build" value="Build" SourcePath="C:\Kiran4" /> 
  </ChildNode>
  </RootNode>  </Root>

From this, I want to create a treeview in WPF and looks like

从这里,我想在WPF中创建一个树视图,看起来像

-Root
 --DeltaTestBaclup
  ---App
    ----Source
    ----Publish
  ---Db
    ----Dev
    ----Build

So please help me to create this treeview.

所以请帮我创建这个树视图。

5 个解决方案

#1


2  

Here is a way to do it programmatically. This is based on this website's solution

这是一种以编程方式执行此操作的方法。这是基于该网站的解决方案

public YourWindow()
{
    InitializeComponent();
    BuildTree(treeView, XDocument.Load(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"testxml.xml")));
}

private void BuildTree(TreeView treeView, XDocument doc)
{
    TreeViewItem treeNode = new TreeViewItem 
    {  
        //Should be Root
        Header = doc.Root.Name.LocalName,
        IsExpanded = true
    };
    treeView.Items.Add(treeNode);
    BuildNodes(treeNode, doc.Root);
}

private void BuildNodes(TreeViewItem treeNode, XElement element)
{
    foreach (XNode child in element.Nodes())
    {
        switch (child.NodeType)
        {
            case XmlNodeType.Element:
                XElement childElement = child as XElement;
                TreeViewItem childTreeNode = new TreeViewItem
                {
                    //Get First attribute where it is equal to value
                    Header = childElement.Attributes().First(s => s.Name == "value").Value ,
                    //Automatically expand elements
                    IsExpanded = true
                };
                treeNode.Items.Add(childTreeNode);
                BuildNodes(childTreeNode, childElement);
                break;
            case XmlNodeType.Text:
                XText childText = child as XText;
                treeNode.Items.Add(new TreeViewItem { Header = childText.Value, });
                break;
        }
    }
}

That code behind will build the tree to your spec. This is the XAML

后面的代码将根据您的规范构建树。这是XAML

<Grid>
    <TreeView Margin="20" Background="LightGray" x:Name="treeView" />
</Grid>

#2


0  

Welcome to *, if you could post some sample xml - it would help to visualise what your working towards. I think you need to use 1 or more HierarchicalDataTemplate.

欢迎来到*,如果你可以发布一些样本xml - 这将有助于可视化你的工作方向。我认为你需要使用一个或多个HierarchicalDataTemplate。

Assuming an xml file called data.xml:

假设一个名为data.xml的xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<root>
     <item>
      <DeltaTestBaclup>aaa</DeltaTestBaclup>
      <App>bbb</App>
      <Source>ccc</Source>
      <Publish>ddd</Publish>
    </item>
    <item>
      <DeltaTestBaclup>aaa</DeltaTestBaclup>
      <App>bbb</App>
      <Source>ccc</Source>
      <Publish>ddd</Publish>
    </item>
</root>

You could use xaml something similar to:

您可以使用xaml类似于:

 <Grid>
        <Grid.DataContext>
            <XmlDataProvider Source="data.xml"></XmlDataProvider>
        </Grid.DataContext>
        <Grid.Resources>
            <HierarchicalDataTemplate x:Key="ItemTemplate" DataType="item">
                <TextBlock>
                    <TextBlock Text="{Binding XPath=DeltaTestBaclup}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=App}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=Source}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=Publish}" />                    
                </TextBlock>
            </HierarchicalDataTemplate>
        </Grid.Resources>

        <TreeView  Name="treeView" 
                   ItemsSource="{Binding Path=.,XPath=/root/item}" 
                   ItemTemplate="{StaticResource ItemTemplate}">      
        </TreeView>
    </Grid>

#3


0  

I know this question was asked a few months ago but I don't think it was answered accurately as I ran into the same problem and none of these suggestions helped me solve it.

我知道这个问题是在几个月前被问到的,但我认为没有准确回答,因为我遇到了同样的问题,这些建议都没有帮我解决。

Here's a link that explains how to populate a treeview from an .xml using winforms:

这是一个链接,解释了如何使用winforms从.xml填充树视图:

http://www.codeproject.com/Articles/12606/Loading-and-Saving-XML-to-and-from-a-TreeView-Cont

I managed to adapt it to wpf so to populate a TreeView using the info in an .xml:

我设法将其改编为wpf,以便使用.xml中的信息填充TreeView:

//First, we'll load the Xml document
XmlDocument xDoc = new XmlDocument();
xDoc.Load(filename);

//Now, clear out the treeview, 
treeView.Items.Clear();

//and add the first (root) node
TreeViewItem treeviewItemRoot   = new TreeViewItem();
treeviewItemRoot.Header         = "Root";

treeView.Items.Add(treeviewItemRoot);

TreeViewItem tNode = new TreeViewItem();
tNode = (TreeViewItem)treeView.Items[0];

//We make a call to addTreeNode, 
//where we'll add all of our nodes
addTreeNode(xDoc.DocumentElement, tNode);



//This function is called recursively until all nodes are loaded
private void addTreeNode(XmlNode xmlNode, TreeViewItem treeNode)
{
    XmlNode xNode;
    TreeViewItem tNode;
    XmlNodeList xNodeList;
    if (xmlNode.HasChildNodes) //The current node has children
    {
        xNodeList = xmlNode.ChildNodes;
        for (int x = 0; x <= xNodeList.Count - 1; x++)
        //Loop through the child nodes
        {
            xNode = xmlNode.ChildNodes[x];

            treeNode.Items.Add(new TreeViewItem());
            tNode = treeNode.Items[x] as TreeViewItem;
            addTreeNode(xNode, tNode);
        }
    }
    else //No children, so add the outer xml (trimming off whitespace)
        treeNode.Header = xmlNode.OuterXml.Trim(); 
}

#4


0  

    class Mapper
{
    private string sourceXmlFile;
    private XDocument xmlData;

    public Mapper(string xmlFilePath)
    {            
        sourceXmlFile = xmlFilePath;           
    }

    private void BuildNodes(TreeViewItem treeNode, XElement element)
    {

        string attributes = "";
        if (element.HasAttributes)
        {
            foreach (var att in element.Attributes())
            {
                attributes += " " + att.Name + " = " + att.Value;
            }
        }

        TreeViewItem childTreeNode = new TreeViewItem
        {
            Header = element.Name.LocalName + attributes,
            IsExpanded = true
        };
        if (element.HasElements)
        {
            foreach (XElement childElement in element.Elements())
            {
                BuildNodes(childTreeNode, childElement);
            }
        }
        else
        {
            TreeViewItem childTreeNodeText = new TreeViewItem
            {
                Header = element.Value,
                IsExpanded = true
            };
            childTreeNode.Items.Add(childTreeNodeText);                    
        }

        treeNode.Items.Add(childTreeNode);
    }



    public void LoadXml(TreeView treeview)
    {
        try
        {
            if (sourceXmlFile != null)
            {
                xmlData = XDocument.Load(sourceXmlFile, LoadOptions.None);
                if (xmlData == null)
                {
                    throw new XmlException("Cannot load Xml document from file : " + sourceXmlFile);
                }
                else
                {
                    TreeViewItem treeNode = new TreeViewItem
                    {
                        Header = sourceXmlFile,
                        IsExpanded = true
                    };


                    BuildNodes(treeNode, xmlData.Root);
                    treeview.Items.Add(treeNode);
                }
            }
            else
            {
                throw new IOException("Xml file is not set correctly.");
            }
        }
        catch (IOException ioex)
        {
            //log
        }
        catch (XmlException xmlex) 
        {
            //log
        }
        catch (Exception ex)
        {
            //log
        }
    }

}

This is the most generic version for every xml structure. For example :

这是每个xml结构的最通用版本。例如 :

    <Catalog>
  <Book id="bk101">
        <Author>Garcia, Debra</Author>
    <Title id="33">XML Developer's Guide</Title>
    <Genre>Computer</Genre>
    <Price>44.95</Price>
    <PublishDate>2000-10-01</PublishDate>
    <Description>An in-depth look at creating applications 
      with XML.</Description>
  </Book>
  <Book id="bk102">
    <Author>Garcia, Debra</Author>
    <Title>Midnight Rain</Title>
    <Genre>Fantasy</Genre>
    <Price>5.95</Price>
    <PublishDate>2000-12-16</PublishDate>
    <Description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</Description>
  </Book>
</Catalog>

Will produce this : 如何使用WPF从XML文件创建treeview?

会产生这个:

#5


-1  

You can read about that here, an example from that site:

你可以在这里阅读,该网站的一个例子:

<TreeView Margin="10,10,0,13" Name="TreeView1" HorizontalAlignment="Left"
 VerticalAlignment="Top" Width="194" Height="200">
    <TreeViewItem Header="Cold Drinks">
        <TreeViewItem Header="Coke"></TreeViewItem>
        <TreeViewItem Header="Pepsi"></TreeViewItem>
        <TreeViewItem Header="Orange Juice"></TreeViewItem>
        <TreeViewItem Header="Milk"></TreeViewItem>
        <TreeViewItem Header="Iced Tea"></TreeViewItem>
        <TreeViewItem Header="Mango Shake"></TreeViewItem>
    </TreeViewItem>
</TreeView>

That would result in this

这将导致这一点

alt text http://www.c-sharpcorner.com/UploadFile/mahesh/WPFTreeView08202008231544PM/Images/WPFTreeViewImg1.jpg

alt text http://www.c-sharpcorner.com/UploadFile/mahesh/WPFTreeView08202008231544PM/Images/WPFTreeViewImg1.jpg

So in your case you need to add some more TreeViewItems and nest them up a bit, play with the above code to get the result you want!

因此,在您的情况下,您需要添加一些TreeViewItems并将它们嵌套一点,使用上面的代码来获得您想要的结果!

#1


2  

Here is a way to do it programmatically. This is based on this website's solution

这是一种以编程方式执行此操作的方法。这是基于该网站的解决方案

public YourWindow()
{
    InitializeComponent();
    BuildTree(treeView, XDocument.Load(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"testxml.xml")));
}

private void BuildTree(TreeView treeView, XDocument doc)
{
    TreeViewItem treeNode = new TreeViewItem 
    {  
        //Should be Root
        Header = doc.Root.Name.LocalName,
        IsExpanded = true
    };
    treeView.Items.Add(treeNode);
    BuildNodes(treeNode, doc.Root);
}

private void BuildNodes(TreeViewItem treeNode, XElement element)
{
    foreach (XNode child in element.Nodes())
    {
        switch (child.NodeType)
        {
            case XmlNodeType.Element:
                XElement childElement = child as XElement;
                TreeViewItem childTreeNode = new TreeViewItem
                {
                    //Get First attribute where it is equal to value
                    Header = childElement.Attributes().First(s => s.Name == "value").Value ,
                    //Automatically expand elements
                    IsExpanded = true
                };
                treeNode.Items.Add(childTreeNode);
                BuildNodes(childTreeNode, childElement);
                break;
            case XmlNodeType.Text:
                XText childText = child as XText;
                treeNode.Items.Add(new TreeViewItem { Header = childText.Value, });
                break;
        }
    }
}

That code behind will build the tree to your spec. This is the XAML

后面的代码将根据您的规范构建树。这是XAML

<Grid>
    <TreeView Margin="20" Background="LightGray" x:Name="treeView" />
</Grid>

#2


0  

Welcome to *, if you could post some sample xml - it would help to visualise what your working towards. I think you need to use 1 or more HierarchicalDataTemplate.

欢迎来到*,如果你可以发布一些样本xml - 这将有助于可视化你的工作方向。我认为你需要使用一个或多个HierarchicalDataTemplate。

Assuming an xml file called data.xml:

假设一个名为data.xml的xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<root>
     <item>
      <DeltaTestBaclup>aaa</DeltaTestBaclup>
      <App>bbb</App>
      <Source>ccc</Source>
      <Publish>ddd</Publish>
    </item>
    <item>
      <DeltaTestBaclup>aaa</DeltaTestBaclup>
      <App>bbb</App>
      <Source>ccc</Source>
      <Publish>ddd</Publish>
    </item>
</root>

You could use xaml something similar to:

您可以使用xaml类似于:

 <Grid>
        <Grid.DataContext>
            <XmlDataProvider Source="data.xml"></XmlDataProvider>
        </Grid.DataContext>
        <Grid.Resources>
            <HierarchicalDataTemplate x:Key="ItemTemplate" DataType="item">
                <TextBlock>
                    <TextBlock Text="{Binding XPath=DeltaTestBaclup}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=App}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=Source}" />
                    <LineBreak></LineBreak>
                    <TextBlock Text="{Binding XPath=Publish}" />                    
                </TextBlock>
            </HierarchicalDataTemplate>
        </Grid.Resources>

        <TreeView  Name="treeView" 
                   ItemsSource="{Binding Path=.,XPath=/root/item}" 
                   ItemTemplate="{StaticResource ItemTemplate}">      
        </TreeView>
    </Grid>

#3


0  

I know this question was asked a few months ago but I don't think it was answered accurately as I ran into the same problem and none of these suggestions helped me solve it.

我知道这个问题是在几个月前被问到的,但我认为没有准确回答,因为我遇到了同样的问题,这些建议都没有帮我解决。

Here's a link that explains how to populate a treeview from an .xml using winforms:

这是一个链接,解释了如何使用winforms从.xml填充树视图:

http://www.codeproject.com/Articles/12606/Loading-and-Saving-XML-to-and-from-a-TreeView-Cont

I managed to adapt it to wpf so to populate a TreeView using the info in an .xml:

我设法将其改编为wpf,以便使用.xml中的信息填充TreeView:

//First, we'll load the Xml document
XmlDocument xDoc = new XmlDocument();
xDoc.Load(filename);

//Now, clear out the treeview, 
treeView.Items.Clear();

//and add the first (root) node
TreeViewItem treeviewItemRoot   = new TreeViewItem();
treeviewItemRoot.Header         = "Root";

treeView.Items.Add(treeviewItemRoot);

TreeViewItem tNode = new TreeViewItem();
tNode = (TreeViewItem)treeView.Items[0];

//We make a call to addTreeNode, 
//where we'll add all of our nodes
addTreeNode(xDoc.DocumentElement, tNode);



//This function is called recursively until all nodes are loaded
private void addTreeNode(XmlNode xmlNode, TreeViewItem treeNode)
{
    XmlNode xNode;
    TreeViewItem tNode;
    XmlNodeList xNodeList;
    if (xmlNode.HasChildNodes) //The current node has children
    {
        xNodeList = xmlNode.ChildNodes;
        for (int x = 0; x <= xNodeList.Count - 1; x++)
        //Loop through the child nodes
        {
            xNode = xmlNode.ChildNodes[x];

            treeNode.Items.Add(new TreeViewItem());
            tNode = treeNode.Items[x] as TreeViewItem;
            addTreeNode(xNode, tNode);
        }
    }
    else //No children, so add the outer xml (trimming off whitespace)
        treeNode.Header = xmlNode.OuterXml.Trim(); 
}

#4


0  

    class Mapper
{
    private string sourceXmlFile;
    private XDocument xmlData;

    public Mapper(string xmlFilePath)
    {            
        sourceXmlFile = xmlFilePath;           
    }

    private void BuildNodes(TreeViewItem treeNode, XElement element)
    {

        string attributes = "";
        if (element.HasAttributes)
        {
            foreach (var att in element.Attributes())
            {
                attributes += " " + att.Name + " = " + att.Value;
            }
        }

        TreeViewItem childTreeNode = new TreeViewItem
        {
            Header = element.Name.LocalName + attributes,
            IsExpanded = true
        };
        if (element.HasElements)
        {
            foreach (XElement childElement in element.Elements())
            {
                BuildNodes(childTreeNode, childElement);
            }
        }
        else
        {
            TreeViewItem childTreeNodeText = new TreeViewItem
            {
                Header = element.Value,
                IsExpanded = true
            };
            childTreeNode.Items.Add(childTreeNodeText);                    
        }

        treeNode.Items.Add(childTreeNode);
    }



    public void LoadXml(TreeView treeview)
    {
        try
        {
            if (sourceXmlFile != null)
            {
                xmlData = XDocument.Load(sourceXmlFile, LoadOptions.None);
                if (xmlData == null)
                {
                    throw new XmlException("Cannot load Xml document from file : " + sourceXmlFile);
                }
                else
                {
                    TreeViewItem treeNode = new TreeViewItem
                    {
                        Header = sourceXmlFile,
                        IsExpanded = true
                    };


                    BuildNodes(treeNode, xmlData.Root);
                    treeview.Items.Add(treeNode);
                }
            }
            else
            {
                throw new IOException("Xml file is not set correctly.");
            }
        }
        catch (IOException ioex)
        {
            //log
        }
        catch (XmlException xmlex) 
        {
            //log
        }
        catch (Exception ex)
        {
            //log
        }
    }

}

This is the most generic version for every xml structure. For example :

这是每个xml结构的最通用版本。例如 :

    <Catalog>
  <Book id="bk101">
        <Author>Garcia, Debra</Author>
    <Title id="33">XML Developer's Guide</Title>
    <Genre>Computer</Genre>
    <Price>44.95</Price>
    <PublishDate>2000-10-01</PublishDate>
    <Description>An in-depth look at creating applications 
      with XML.</Description>
  </Book>
  <Book id="bk102">
    <Author>Garcia, Debra</Author>
    <Title>Midnight Rain</Title>
    <Genre>Fantasy</Genre>
    <Price>5.95</Price>
    <PublishDate>2000-12-16</PublishDate>
    <Description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</Description>
  </Book>
</Catalog>

Will produce this : 如何使用WPF从XML文件创建treeview?

会产生这个:

#5


-1  

You can read about that here, an example from that site:

你可以在这里阅读,该网站的一个例子:

<TreeView Margin="10,10,0,13" Name="TreeView1" HorizontalAlignment="Left"
 VerticalAlignment="Top" Width="194" Height="200">
    <TreeViewItem Header="Cold Drinks">
        <TreeViewItem Header="Coke"></TreeViewItem>
        <TreeViewItem Header="Pepsi"></TreeViewItem>
        <TreeViewItem Header="Orange Juice"></TreeViewItem>
        <TreeViewItem Header="Milk"></TreeViewItem>
        <TreeViewItem Header="Iced Tea"></TreeViewItem>
        <TreeViewItem Header="Mango Shake"></TreeViewItem>
    </TreeViewItem>
</TreeView>

That would result in this

这将导致这一点

alt text http://www.c-sharpcorner.com/UploadFile/mahesh/WPFTreeView08202008231544PM/Images/WPFTreeViewImg1.jpg

alt text http://www.c-sharpcorner.com/UploadFile/mahesh/WPFTreeView08202008231544PM/Images/WPFTreeViewImg1.jpg

So in your case you need to add some more TreeViewItems and nest them up a bit, play with the above code to get the result you want!

因此,在您的情况下,您需要添加一些TreeViewItems并将它们嵌套一点,使用上面的代码来获得您想要的结果!