0

I have the following ViewModel class:

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        m_folders = new List<Folder>();
    }

    private List<Folder> m_folders;
    public List<Folder> Folders
    {
        get { return m_folders; }
        set
        {
            m_folders = value;
            NotifiyPropertyChanged("Folders");
        }
    }

    void NotifiyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

And the Folder class:

public class Folder
{
    public Folder()
    {
        Folders = new List<Folder>();
    }

    public string FullPath
    {
        get;
        set;
    }

    public string FolderLabel
    {
        get;
        set;
    }

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

The ViewModel class is Binded to a TreeView like this:

    <TreeView ItemsSource="{Binding Folders}" Margin="10" Height="200" Name="treeView">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Folders}" DataType="{x:Type local:Folder}" >
                <TextBlock Text="{Binding FolderLabel}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

The binding itself is done in the Window Load event and then I populate the object:

    public ViewModel model = new ViewModel();

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        treeView.DataContext = model;

        //add Root items
        model.Folders.Add(new Folder { FolderLabel = "Dummy1", FullPath = @"C:\dummy1" });
        model.Folders.Add(new Folder { FolderLabel = "Dummy2", FullPath = @"C:\dummy2" });
        model.Folders.Add(new Folder { FolderLabel = "Dummy3", FullPath = @"C:\dummy3" });
        model.Folders.Add(new Folder { FolderLabel = "Dummy4", FullPath = @"C:\dummy4" });

        //add sub items
        model.Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy11", FullPath = @"C:\dummy11" });
        model.Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy12", FullPath = @"C:\dummy12" });
        model.Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy13", FullPath = @"C:\dummy13" });
        model.Folders[0].Folders.Add(new Folder { FolderLabel = "Dummy14", FullPath = @"C:\dummy14" });

        model.Folders[0].Folders[0].Folders.Add(new Folder { FolderLabel = "MyDummy1", FullPath = @"xxxxxx" });
    }

So far, so good. Everything works nice. Then I add a button to the Form and remove the populate code from Form load and put it on the Button click. It does not work anymore. The TreeView binding does not work anymore. Am I doing something wrong?

1 Answer 1

3

Because you are binding TreeView's item source to a List<Folder>. Initial binding will work, but further updates won't be reflected in the UI, because List<T> internally do not implement INotifyPropertyChanged and INotifyCollectionChanged interfaces. You need to replace List<Folder> with ObservableCollection<Folder>.

Sign up to request clarification or add additional context in comments.

1 Comment

Works like a charm now. Thanks for the explanation too

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.