Điều này có vẻ với tôi như là một điều hợp lý đơn giản để thực hiện nếu bạn thiết kế mô hình quan điểm của bạn đúng cách.
Bạn về cơ bản thiết kế các mục giống như cách bạn làm nếu hiển thị chúng trong lưới dữ liệu thông thường, tức là mỗi mục có thuộc tính cho mỗi cột. Trong mọi khả năng, mô hình dữ liệu cơ bản của bạn là phân cấp, nhưng bộ sưu tập lưới được ràng buộc sẽ bị phẳng, nghĩa là sẽ chứa một mục cho mỗi nút trong cấu trúc phân cấp không phụ thuộc vào các mối quan hệ cha/con.
Mô hình chế độ xem mục có một số thuộc tính bổ sung: Level
, Children
, IsExpanded
và IsVisible
. Level
là số lượng tổ tiên của nút, Children
chứa các nút kiểu xem con, IsExpanded
được sử dụng trong giao diện người dùng và IsVisible
là đúng nếu nút hiển thị. Nó cũng thực hiện một tính chất gọi là VisibleDescendants
:
public IEnumerable<NodeViewModel> VisibleDescendants
{
get
{
return Children
.Where(x => x.IsVisible)
.SelectMany(x => (new[] {x}).Concat(x.VisibleDescendants)));
}
}
Bạn sử dụng Level
, HasChildren
, và IsExpanded
theo phong cách cho các mục trong cột đầu tiên của kiểm soát: họ kiểm soát lề trái và những loại biểu tượng (nếu có) là hiển thị.
Bạn cũng cần triển khai các thuộc tính ExpandCommand
và CollapseCommand
. ExpandCommand
được bật nếu Children.Any()
là đúng và IsExpanded
là sai và CollapseCommand
được bật nếu Children.Any()
là đúng và IsExpanded
là đúng. Các lệnh này, khi được thực thi, thay đổi giá trị của IsExpanded
.
Và đây là nơi thú vị. Cách đơn giản để thực hiện điều này có thể phù hợp với bạn: các mục được hiển thị bởi mô hình chế độ xem gốc có thuộc tính Items
không phải là bộ sưu tập. Thay vào đó, nó là một điều tra viên rằng đi xuống chuỗi các mô hình xem đứa trẻ và chỉ có hiệu suất các nút có thể nhìn thấy:
public IEnumerable<NodeViewModel> Items
{
get
{
return _Items
.Where(x => x.IsVisible)
.SelectMany(x => (new[] {x}).Concat(x.VisibleDescendants));
}
}
Bất cứ khi nào bất kỳ của hậu duệ IsVisible
thay đổi sở hữu, quan điểm mô hình mẹ tăng PropertyChanged
cho Items
bất động sản, trong đó lực lượng dữ liệu lưới để lặp lại. Có một thực hiện đơn giản hơn nữa, nơi bạn làm cho thuộc tính Items
một lớp thực hiện INotifyCollectionChanged
và tăng các sự kiện thích hợp CollectionChanged
khi nút hậu duệ trở nên có thể nhìn thấy/vô hình, nhưng bạn chỉ muốn đến đó nếu hiệu suất là một vấn đề .
Nhưng tôi muốn kết hợp nó với một DataGrid (có thể chỉnh sửa) – Shimmy
+1 @Shimmy Xem com một phần của http://www.codeproject.com/KB/WPF/wpf_treelistview_control.aspx. nó cho thấy làm thế nào để sử dụng nó với một mạng lưới thay vì một listview – k3b
@ k3b bạn nên đã hướng dẫn này @ Hedge. Tôi nghĩ rằng đây không thực sự là một vấn đề @Shimmy quan tâm đến nữa ... chỉ cần nói ... –