将树视图绑定到EF实体图

本文关键字:EF 实体图 绑定 视图 | 更新日期: 2023-09-27 18:06:03

我正在做一个学习WPF MVVM的小项目。一切都很好,直到我遇到了这个障碍:我试图将树视图绑定到一个可观察集合,以显示部门和他们的教师。数据是主动加载的,所以不能延迟加载。

这是我的视图模型:
public class NavigationTreeViewModel : BindableBase
{
    private CV.Model.Context.CVContext _dbContext;
    public NavigationTreeViewModel()
    {
        _dbContext = new Model.Context.CVContext();
        LoadDepartments();
    }
    private void LoadDepartments()
    {
        var result = _dbContext.Departments.Include(a => a.Teachers);
        _departments = new ObservableCollection<Department>(result.ToList());
    }
    private ObservableCollection<Teacher> _teachers;
    public ObservableCollection<Teacher> Teachers
    {
        get { return _teachers; }
        set { SetProperty(ref _teachers, value); }
    }
    private ObservableCollection<Department> _departments;
    public ObservableCollection<Department> Departments
    {
        get { return _departments; }
        set { SetProperty(ref _departments, value); }
    }
}

我可以设置我的绑定来显示部门和老师的名字,像这样:

<UserControl x:Class="CV.Modules.Views.NavigationTreeView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:vm="clr-namespace:CV.Modules.ViewModels"
         xmlns:prism="http://prismlibrary.com/"             
         prism:ViewModelLocator.AutoWireViewModel="True">
<UserControl.DataContext>
    <vm:NavigationTreeViewModel/>
</UserControl.DataContext>
<TreeView ItemsSource="{Binding Departments}" Margin="5">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Teachers}">
            <TextBlock Text="{Binding Name}"/>
        </HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>
</UserControl>

但是,如果我想在父实体中显示部门名称,在子实体中显示教师的姓氏,这将不起作用。因此,我根据本文将树视图的模板更改为控件的资源。以下是我所做的:

<UserControl.Resources>
    <DataTemplate x:Key="TeacherLevel">
        <TextBlock Text="{Binding LastName}"/>
    </DataTemplate>
    <HierarchicalDataTemplate x:Key="DepartmentLevel"
                              ItemsSource="{Binding Departments}"
                              ItemTemplate="{StaticResource TeacherLevel}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
</UserControl.Resources>
<TreeView ItemTemplate="{StaticResource DepartmentLevel}"
          ItemsSource="{Binding Departments}"
          Margin="5"/>

这样只显示部门的名字而不显示老师的姓。我注意到,当试图访问我的实体的属性时,没有智能感知是可用的,我唯一可用的是我的viewModel中的属性。在我的第一次绑定尝试中,我可以看到所有的部门属性,但在我的第二次绑定尝试中却看不到。

我的问题是,我如何将树视图绑定到显示每个级别不同属性的多层次实体图?

我在这里错过了一些非常基本的东西,但我不能把我的手指放在它上面。如有任何帮助,不胜感激。

谢谢

将树视图绑定到EF实体图

感谢@Sir Rufo提供的链接。

我的模板中缺少的是我要绑定到的数据的类型。在HierarchicalDataTemplate中的DataType是必需的,以便知道我绑定到哪个属性。

两种建议的解决方案都定义了要在ViewModel中绑定到树视图的实体。

我的模型是在不同的程序集中定义的,所以我最终在我的视图中引用了我的模型。这样我的视图就知道我的模型,我很确定我这样做是在打破MVVM模式。我不喜欢仅仅为了给我的视图提供数据绑定而创建额外的相同类的想法。

下面是我的代码:
<UserControl x:Class="CV.Modules.Views.NavigationTreeView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:vm="clr-namespace:CV.Modules.ViewModels"
         xmlns:data="clr-namespace:CV.Model;assembly=CV.Model"
         xmlns:prism="http://prismlibrary.com/"             
         prism:ViewModelLocator.AutoWireViewModel="True">
<UserControl.Resources>
    <HierarchicalDataTemplate ItemsSource="{Binding Teachers}"
                              DataType="{x:Type data:Department}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type data:Teacher}">
        <TextBlock Text="{Binding LastName}" />
    </DataTemplate>
</UserControl.Resources>
<TreeView ItemsSource="{Binding Departments}" Margin="5"/>
</UserControl>

我从SO标记链接作为答案,因为它指向我如何回答我的问题。当我找到一个不会用模型实体污染视图的解决方案时,我将在将来编辑这个答案。欢呼声