anuj kumar Jha
anuj kumar Jha

Reputation: 63

Binding not working properly in treeview WPF

I have an Employee Class as shown below:

public class Employee : INotifyPropertyChanged
    {
        public Employee()
        {
            _subEmployee = new ObservableCollection<Employee>();
        }

        public string Name { get; set; }

        public ObservableCollection<Employee> SubEmployee
        {
            get { return _subEmployee; }
            set
            {
                _subEmployee = value;
                NotifiyPropertyChanged("SubEmployee");
            }
        }

        ObservableCollection<Employee> _subEmployee;

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

I am creating a collection of employee class in Main window constructor and adding it to an observable collection of employee as shown below:

public partial class MainWindow : Window
    {
        public ObservableCollection<Employee> Emp { get; private set; }
        public MainWindow()
        {
            InitializeComponent();
            Emp = new ObservableCollection<Employee>();
            Emp.Add(new Employee(){Name = "Anuj"});
            Emp.Add(new Employee() { Name = "Deepak" });
            Emp.Add(new Employee() { Name = "Aarti" });

            Emp[0].SubEmployee.Add(new Employee(){Name = "Tonu"});
            Emp[0].SubEmployee.Add(new Employee() { Name = "Monu" });
            Emp[0].SubEmployee.Add(new Employee() { Name = "Sonu" });

            Emp[2].SubEmployee.Add(new Employee() { Name = "Harsh" });
            Emp[2].SubEmployee.Add(new Employee() { Name = "Rahul" });
            Emp[2].SubEmployee.Add(new Employee() { Name = "Sachin" });
            this.DataContext = this;
        }      
    }

I have set the DataContext as self. Now, in xaml file I have created a hierarchical template of treeview and binded data as shown below:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView ItemsSource="{Binding}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding SubEmployee}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

    </Grid>
</Window>

Now when I keep, TreeView ItemsSource="{Binding Emp}" , binding works properly and I can see the tree view structure after running the code. However when I keep TreeView ItemsSource="{Binding}", I see no result after running the code.

To my understanding, keeping ItemSource = "{Binding}" means I am binding to the evaluated value of the current datacontext. As my datacontext is set to self, ItemSource = "{Binding}" should mean I am binding to the only property of DataContext i.e. Emp and I should get proper result.

Please help me in understanding the problem I am getting in keeping binding as ItemSource = "{Binding}".

Upvotes: 4

Views: 1717

Answers (1)

blins
blins

Reputation: 2535

"To my understanding, keeping ItemSource = "{Binding}" means I am binding to the evaluated value of the current datacontext."

Correct AND that is the issue. ItemsSource expects the binding source to be of type IEnumerable but you are binding to Window.

"...should mean I am binding to the only property of DataContext i.e. Emp and I should get proper result."

No. No such "single property" assumption exists in WPFs binding conventions.

Change...

this.DataContext = this;

To...

this.DataContext = Emp;

Or, alternatively, change binding in XAML and specify the correct member on the DataContext to bind to using Path...

<TreeView ItemsSource="{Binding Path=Emp}">

Upvotes: 6

Related Questions