2

I want to view a folder structure in a treeview using a databinding. The folder class just has a property list of children and a property name.

If something changes it will fire the according event. This is it:

    public class Folder : INotifyPropertyChanged, INotifyCollectionChanged
    {    
        public event PropertyChangedEventHandler PropertyChanged;           
        public event NotifyCollectionChangedEventHandler CollectionChanged; 

        public Folder(string name)
        {
            this.Name = name;
            this.ContentFolders = new List<Folder>();
        }

        public List<Folder> ContentFolders { get; set; }

        public void AddFolder(Folder f)
        {
            this.ContentFolders.Add(f);

            if (this.CollectionChanged != null)
            {
                this.NotifyCollectionChanged(
                      new NotifyCollectionChangedEventArgs(
                          NotifyCollectionChangedAction.Add, f));
            }
            this.PropertyChanged(this, new PropertyChangedEventArgs("ContentFolders"));
        }

        private void NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            lock (CollectionChanged)
            {
                if (CollectionChanged != null)
                {
                    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => CollectionChanged(this, e)));
                }
            }
        }

        private string name;

        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                if (this.name != value)
                {
                    this.name = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(
                            this, new PropertyChangedEventArgs("Name"));
                    }
                }
            }
        }

    }

This is my GUI, which shows the root folder in a treeview:

    <Window x:Class="WpfApplication2.MyWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication2="clr-namespace:WpfApplication2"
            Title="MyWindow" Height="300" Width="300" xmlns:u="clr-namespace:UpdateControls.XAML;assembly=UpdateControls.XAML">
      <StackPanel>
        <StackPanel.Resources>
          <HierarchicalDataTemplate DataType="{x:Type WpfApplication2:Folder}"
                                    ItemsSource="{Binding Path=ContentFolders}">
            <TextBlock Text="{Binding Path=Name}" />
          </HierarchicalDataTemplate>
        </StackPanel.Resources>
        <TreeView Name="TreeviewScenario">
          <TreeViewItem Header="{Binding Path=RootFolder.Name}"
                        ItemsSource="{Binding Path=RootFolder.ContentFolders}" />
        </TreeView>
        <Button Content="Add Folder" Click="Button_Click" />
      </StackPanel>
    </Window>

The according MyWindow.xaml.cs class has a property Folder and adds some content. It has also a method for the button to add a new folder if it becomes clicked.

public partial class MyWindow : Window
{
    public Folder RootFolder { get; set; }

    public MyWindow()
    {
        this.RootFolder = new Folder("root");
        this.RootFolder.ContentFolders.Add(new Folder("1"));
        this.RootFolder.ContentFolders.Add(new Folder("12"));
        this.RootFolder.ContentFolders.Add(new Folder("13"));
        this.RootFolder.ContentFolders.Add(new Folder("14"));
        this.RootFolder.ContentFolders.Add(new Folder("15"));

        Folder aFolder = new Folder("aFolder");
        aFolder.ContentFolders.Add(new Folder("2"));
        aFolder.ContentFolders.Add(new Folder("21"));
        aFolder.ContentFolders.Add(new Folder("22"));
        aFolder.ContentFolders.Add(new Folder("23"));
        aFolder.ContentFolders.Add(new Folder("24"));

        this.RootFolder.ContentFolders.Add(aFolder);

        this.DataContext = this;
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Folder c = new Folder("a new Folder");
        this.RootFolder.AddFolder(c);
    }
}

The Gui will be calles by a simple Main method with:

    new MyWindow();

If I start, the treeview looks fine, it has all the items, which have been added in the MyWindow.xaml.cs.

But If I click the button, no new items will be shown. If I click the button before I expand the treeview, the new items will be there...

So the view seems not to be updated...

Can anybody see, what I have done wrong?

Fenton
  • 241,084
  • 71
  • 387
  • 401
clx
  • 794
  • 2
  • 8
  • 19

1 Answers1

1

Change the ContentFolders in your Folder class to an ObservableCollection<> instead of a List<>

    public ObservableCollection<Folder> ContentFolders { get; set; }
Eirik
  • 4,135
  • 27
  • 29