简体   繁体   中英

Why doesn't the following WPF treeview work?

It's been a really long time since iv'e used WPF, now, required to do a small project on it, I have a really weird problem making a simple databinded treeview.

the main window so far:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();

        populateTreeview();
    }

    private XMLDataNode tree;

 public XMLDataNode TreeRoot
 {
     get { return tree; }
     set 
     { 
          tree = value;
          NotifyPropertyChanged("TreeRoot");
     }
 }

    //Open the XML file, and start to populate the treeview
    private void populateTreeview()
    {
        {
            try
            {
                //Just a good practice -- change the cursor to a 
                //wait cursor while the nodes populate    
                this.Cursor = Cursors.Wait;
                string filePath = System.IO.Path.GetFullPath("TestXML.xml");
                TreeRoot = RXML.IOManager.GetXMLFromFile(filePath).Last();
            }
            catch (XmlException xExc)
            //Exception is thrown is there is an error in the Xml
            {
                MessageBox.Show(xExc.Message);
            }
            catch (Exception ex) //General exception
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.AppStarting; //Change the cursor back
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

The data class i'm working with which loads XML nodes into itself:

public class XMLDataNode
{
    public XmlNode node;
    public string Title;
    public List<XMLDataNode> Children;

    public XMLDataNode(XmlNode XMLNode)
    {
        this.node = XMLNode;
        this.Title = node.ToString();
        Children = new List<XMLDataNode>();
        foreach (XmlNode item in XMLNode.ChildNodes)
        {
            Children.Add(new XMLDataNode(item));
        }
    }

the mainwindow XAML:

<Window x:Class="RotemXMLEditor.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="800" Width="1000" x:Name="me">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>

    <TreeView Grid.Row="1" x:Name="treeView" Background="White" ItemsSource="{Binding ElementName=me, Path=TreeRoot}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Title}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>

    </TreeView>
</Grid>

The current output is an empty treeview, with nothing in it, even though the databinded object is filled with info.

I realize it's probably a silly mistake, but I really can't seem to find the mistake, Help?

Can you turn this property in a collection that implements IEnumerable?

public XMLDataNode TreeRoot

eg:

public XMLDataNode[] TreeRoots

The ItemsSource of the TreeView expects a type that implements IEnumerable

This works for me:

<TreeView Grid.Row="1" x:Name="treeView" Background="White" ItemsSource="{Binding ElementName=me, Path=TreeRoots}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Title}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

private XMLDataNode[] treeRoots;
public XMLDataNode[] TreeRoots
{
    get { return treeRoots; }
    set
    {
        treeRoots = value;
        NotifyPropertyChanged("TreeRoots");
    }
}

private void populateTreeview()
    {
        {
            try
            {
                //Just a good practice -- change the cursor to a 
                //wait cursor while the nodes populate    
                this.Cursor = Cursors.Wait;
                string filePath = System.IO.Path.GetFullPath("TestXML.xml");
                TreeRoot = RXML.IOManager.GetXMLFromFile(filePath).Last();
                TreeRoots = new[] { TreeRoot };
            }
            catch (XmlException xExc)

I have found the solution.

WPF databinding can only work (which I forgot) with properties, not fields, even though the fields are public, changing all the data binded fields to actual properties solves this problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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