将TreeView绑定到EF实体的图形

时间:2016-09-07 21:18:46

标签: c# wpf entity-framework mvvm treeview

我正在开发一个小项目来学习学习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>

但是,如果我想显示父实体中部门的名称和子实体中教师的姓氏,则无法使用。所以我根据这个article将树视图的模板更改为控件的资源。这是我做的:

<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"/>

这样只会显示部门的名称,但不会显示教师的姓氏。 我注意到在尝试访问我的实体的属性时没有可用的Intellisense,唯一可用的是我的viewModel中的属性。在我的第一次绑定尝试中,我可以看到所有部门属性,但不能在我的第二次绑定尝试中。

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

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

由于

1 个答案:

答案 0 :(得分:0)

感谢@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的链接作为答案,因为它指出了如何回答我的问题。 当我找到一个不会污染我的模型实体的视图的解决方案时,我将来会编辑这个答案。 干杯