Blog của Lê Văn Luật

Đời người thì có hạn mà sự học thì vô hạn!

WPF: Hierarchical Template TreeView với CodeFirst EF

Trong trường hợp cần hiển thị dữ liệu phân cấp ta thường sử dụng TreeView. Ví dụ sau minh họa sử dụng TreeView Hierarchical Template với EF CodeFirst.

Giả sử có dữ liệu phân cấp dạng sau:

1. Phòng Nhân sự
a. Trần Văn Tuấn
b. Nguyễn Thị Thành

2. Phòng Hành chính
a. Nguyễn Văn Hùng
b. Đặng Thị Tâm
c. Hoàng Văn Bách

Mô hình CodeFirst như sau (lưu ý: MyDbInitializer để khởi tạo dữ liệu thử):

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;

namespace HierarchicalTreeview
{
    class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyDbContext>
    {
        protected override void Seed(MyDbContext context)
        {
            var p = new List<Phong>()
            {
                new Phong() {P=1, Ten="Phòng Nhân sự"},
                new Phong() {P=2, Ten="Phòng Hành chính"}
            };

            foreach (var t in p)
                context.Phong.Add(t);
            var nv = new List<NhanVien>()
            {
                new NhanVien(){NV=1, Ho="Trần Văn", Ten="Tuấn", Phong=context.Phong.Local.ElementAt(0)},
                new NhanVien(){NV=2, Ho="Nguyễn Thị", Ten="Thành", Phong=context.Phong.Local.ElementAt(0)},
                new NhanVien(){NV=3, Ho="Nguyễn Văn", Ten="Hùng", Phong=context.Phong.Local.ElementAt(1)},
                new NhanVien(){NV=4, Ho="Đặng Thị", Ten="Tâm", Phong=context.Phong.Local.ElementAt(1)},
                new NhanVien(){NV=5, Ho="Hoàng Văn", Ten="Bách", Phong=context.Phong.Local.ElementAt(1)}
            };

            foreach (var t in nv)
                context.NhanVien.Add(t);
        }
    }
    class MyDbContext : DbContext
    {
        public DbSet<Phong> Phong { get; set; }
        public DbSet<NhanVien> NhanVien { get; set; }
        public MyDbContext()
            : base("HierarchicalTreeview")
        {
            Database.SetInitializer<MyDbContext>(new MyDbInitializer());
        }
    }

    [Table("Phong")]
    class Phong
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int P { get; set; }
        public string Ten { get; set; }
        public virtual ICollection<NhanVien> NhanVien { get; set; }
    }

    [Table("NhanVien")]
    class NhanVien
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int NV { get; set; }
        public string Ho { get; set; }
        public string Ten { get; set; }
        public virtual Phong Phong { get; set; }
    }
}

Mã XAML:

<Window x:Class="HierarchicalTreeview.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"         Loaded="Window_Loaded" Closing="Window_Closing">
    <Window.Resources>
        <HierarchicalDataTemplate x:Key="NhanVienTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition Width="50"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Ho}"/>
                <TextBlock Grid.Column="1" Text="{Binding Ten}"/>
            </Grid>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="PhongTemplate"                                   ItemsSource="{Binding NhanVien}"                                   ItemTemplate="{StaticResource NhanVienTemplate}">
            <TextBlock Text="{Binding Ten}"/>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <TreeView Name="trvPhong" ItemsSource="{Binding}" ItemTemplate="{DynamicResource PhongTemplate}"/>
</Window>

Behind code:

using System.Windows;
using System.Data.Entity;

namespace HierarchicalTreeview
{
    public partial class MainWindow : Window
    {
        MyDbContext data;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            data = new MyDbContext();
            data.Phong.Load();
            data.NhanVien.Load();
            trvPhong.ItemsSource = data.Phong.Local;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            data.SaveChanges();
        }
    }
}

Kết quả như sau:

Cơ sở dữ liệu được tạo:
p00002

Màn hình form:
p00001

Để chọn (select) node đầu tiên (node 0) và mở rộng nó (expand) bằng mã lệnh:

 TreeViewItem i = trvPhong.ItemContainerGenerator.ContainerFromIndex(NodeChon) as TreeViewItem;
 i.IsSelected = true;
 i.IsExpand();

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

Information

This entry was posted on 24/08/2014 by in Lập trình C# & WPF.

Điều hướng

%d bloggers like this: