C# TreeView';的子节点无法反映绑定中的更改

C# TreeView';的子节点无法反映绑定中的更改,c#,wpf,mvvm,binding,treeview,C#,Wpf,Mvvm,Binding,Treeview,只有顶级节点可以反映后面的更改,但它们的节点不能。有什么想法吗?谢谢在下面的代码中,它应该同时添加一个新经理和一个新员工 模型 公共类员工 { 公共Guid EmployeeId{get;set;} 公共字符串EmployeeName{get;set;} } 公共班级经理 { 公共Guid ManagerId{get;set;} 公共字符串管理器名称{get;set;} 公共IEnumerable雇员{get;set;} } 视图模型 公共类TreeWindowViewModel:INoti

只有顶级节点可以反映后面的更改,但它们的节点不能。有什么想法吗?谢谢在下面的代码中,它应该同时添加一个新经理和一个新员工

模型
公共类员工
{
公共Guid EmployeeId{get;set;}
公共字符串EmployeeName{get;set;}
}
公共班级经理
{
公共Guid ManagerId{get;set;}
公共字符串管理器名称{get;set;}
公共IEnumerable雇员{get;set;}
}
视图模型
公共类TreeWindowViewModel:INotifyPropertyChanged
{
私有列表employeeList=新列表();
私有列表管理器列表=新列表();
公共树WindowViewModel()
{
//创建用于测试的假数据
添加(新员工(){EmployeeId=Guid.NewGuid(),EmployeeName=“Adam”});
添加(新员工(){EmployeeId=Guid.NewGuid(),EmployeeName=“Benson”});
添加(新员工(){EmployeeId=Guid.NewGuid(),EmployeeName=“cooster”});
添加(新员工(){EmployeeId=Guid.NewGuid(),EmployeeName=“Denny”});
添加(新员工(){EmployeeId=Guid.NewGuid(),EmployeeName=“Ellis”});
//创建ObservableCollection对象
员工=新的可观察集合(员工列表);
//创建2个经理,并使
经理manager1=新经理()
{
ManagerId=Guid.NewGuid(),
ManagerName=“弗兰克”,
员工=新列表(员工列表)
};
经理2=新经理()
{
ManagerId=Guid.NewGuid(),
ManagerName=“绿色”,
员工=新列表(员工列表)
};
managerList.Add(manager1);
managerList.Add(manager2);
经理=新的可观察集合(经理列表);
}
私人收款经理;
公共收款经理
{
得到
{
回报经理;
}
设置
{
经理=价值;
OnPropertyChanged(新PropertyChangedEventArgs(“经理”);
}
}
私人收集员工;
公开收集雇员
{
得到
{
返回员工;
}
设置
{
员工=价值;
OnPropertyChanged(新PropertyChangedEventArgs(“员工”));
}
}
公共事件属性更改事件处理程序属性更改;
PropertyChanged上的公共无效(PropertyChangedEventArgs e)
{
if(PropertyChanged!=null)
{
财产变更(本,e);
}
}
}
XAML

XAML.CS
命名空间绑定测试
{
/// 
///TreeWindow.xaml的交互逻辑
/// 
公共部分类树窗口:窗口
{
公共树丛()
{
初始化组件();
this.DataContext=newtreewindowviewmodel();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
TreeWindowViewModel ds=this.DataContext作为TreeWindowViewModel;
如果(ds!=null)
{
添加(new Manager(){ManagerId=Guid.NewGuid(),ManagerName=“new Manager”});
添加(new Employee(){EmployeeId=Guid.NewGuid(),EmployeeName=“new Employee”});
}
}
}
}


无法获得预期结果的主要原因是,您正在将
员工
添加到
公共可观察集合员工
,而用户界面上没有该限制。您真正看到的是绑定到
TreeView
经理的初始列表。

public class Employee
{
    public Guid EmployeeId { get; set; }
    public string EmployeeName { get; set; }
}

public class Manager
{
    public Guid ManagerId { get; set; }
    public string ManagerName { get; set; }
    public IEnumerable<Employee> Employees { get; set; }
}
public class TreeWindowViewModel : INotifyPropertyChanged
{
    private List<Employee> employeeList = new List<Employee>();
    private List<Manager> managerList = new List<Manager>();

    public TreeWindowViewModel()
    {
        //Create fake data for testing
        employeeList.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "Adam" });
        employeeList.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "Benson" });
        employeeList.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "Cooker" });
        employeeList.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "Denny" });
        employeeList.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "Ellis" });

        //Create ObservableCollection object
        employees = new ObservableCollection<Employee>(employeeList);

        //Create 2 managers and make 
        Manager manager1 = new Manager()
        {
            ManagerId = Guid.NewGuid(),
            ManagerName = "Frank",
            Employees = new List<Employee>(employeeList)
        };

        Manager manager2 = new Manager()
        {
            ManagerId = Guid.NewGuid(),
            ManagerName = "Green",
            Employees = new List<Employee>(employeeList)
        };

        managerList.Add(manager1);
        managerList.Add(manager2);

        managers = new ObservableCollection<Manager>(managerList);

    }

    private ObservableCollection<Manager> managers;
    public ObservableCollection<Manager> Managers
    {
        get
        {
            return managers;
        }
        set
        {
            managers = value;

            OnPropertyChanged(new PropertyChangedEventArgs("Managers"));
        }
    }

    private ObservableCollection<Employee> employees;
    public ObservableCollection<Employee> Employees
    {
        get
        {
            return employees;
        }
        set
        {
            employees = value;

            OnPropertyChanged(new PropertyChangedEventArgs("Employees"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }
}
    <Window x:Class="BindingTests.TreeWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:m="clr-namespace:BindingTests.Models"
        Title="TreeWindow" Height="300" Width="300">
    <Window.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Employees}" DataType="{x:Type m:Manager}">
            <TextBlock Text="{Binding Path=ManagerName}"/>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type m:Employee}">
            <TextBlock Text="{Binding Path=EmployeeName}"/>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TreeView ItemsSource="{Binding Managers, Mode=OneWay, NotifyOnSourceUpdated=True}" Grid.Column="0">
            <TreeView.Resources>
                <Style TargetType="Label">
                    <Setter Property="Margin" Value="0"/>
                    <Setter Property="Padding" Value="0"/>
                </Style>
                <Style TargetType="TreeViewItem">
                    <Setter Property="Margin" Value="0"/>
                    <Setter Property="Padding" Value="0"/>
                </Style>
            </TreeView.Resources>
        </TreeView>
        <StackPanel Grid.Column="1">
            <Button Content="Click me to add a manager" Click="Button_Click" Height="30"/>
        </StackPanel>
    </Grid>
</Window>
    namespace BindingTests
    {
    /// <summary>
    /// Interaction logic for TreeWindow.xaml
    /// </summary>
    public partial class TreeWindow : Window
    {
        public TreeWindow()
        {
            InitializeComponent();

            this.DataContext = new TreeWindowViewModel();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TreeWindowViewModel ds = this.DataContext as TreeWindowViewModel;
            if (ds != null)
            {
                ds.Managers.Add(new Manager() { ManagerId = Guid.NewGuid(), ManagerName = "New Manager" });
                ds.Employees.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "New Employee"});
            }
        }
    }
}
if (ds != null)
{
    ds.Managers.Add(new Manager() { ManagerId = Guid.NewGuid(), ManagerName = "New Manager" });
    ds.Managers[0].Employees.Add(new Employee() { EmployeeId = Guid.NewGuid(), EmployeeName = "New Employee"});
}
if(ds.SelectedItem is Manager)
{
    (ds.SelectedItem as Manager).Employees.Add( ... );
}