[SilverLight]MVVM下绑定TreeView

文章使用的是MVVMLight框架,下载地址:http://mvvmlight.codeplex.com/

首先要对TreeView进行扩展,使得它能够有Command,里面需要用到Prism,下载地址:http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=28950

参考文章:http://www.silverlightshow.net/items/Make-the-TreeView-control-to-be-MVVM-compliant.aspx

需要先添加引用:

1 xmlns:tree="clr-namespace:[your namespace]"

View代码:

 1 <tree:TreeViewWithCommand   ItemsSource="{Binding Root,Mode=TwoWay}" 
 2                             tree:ItemExpanded.Command="{Binding ItemExpanded}"
 3                             tree:SelectedItemChanged.Command="{Binding ItemSelected}">
 4      <tree:TreeViewWithCommand.ItemTemplate>
 5           <c:HierarchicalDataTemplate ItemsSource="{Binding Children,Mode=TwoWay}"   >
 6                  <TextBlock Text="{Binding Current. Value,Mode=TwoWay}"></TextBlock>
 7           </c:HierarchicalDataTemplate>
 8      </tree:TreeViewWithCommand.ItemTemplate>
 9 </tree:TreeViewWithCommand>

然后新增一个View用来存储TreeView的数据:

View Code
 1 public class Tree<T> 
 2     {
 3         public ObservableCollection<Tree<T>> Children { get; set; }
 4         public T Current { get; set; }
 5         
 6         
 7 
 8         public Tree(T parent)
 9         {
10             this.Current = parent;
11             this.Children = new ObservableCollection<Tree<T>>();
12         }
13 
14         public Tree(T parent, T child)
15         {
16             this.Current = parent;
17             this.Children = new ObservableCollection<Tree<T>>();
18             this.Children.Add(new Tree<T>(child));
19         }
20 
21         
22     }
View Code
1 public class Product
2         {
3             public int ProductId { get; set; }
4             public string ProductName { get; set; }
5         }

在ViewModel(记得继承ViewModelBase)中添加属性用来存放TreeView的数据:

View Code
 1 private ObservableCollection<Tree<Product>> _root;
 2         public ObservableCollection<Tree<Product>> Root
 3         {
 4             get { return _root; }
 5             private set
 6             {
 7                 if (!ReferenceEquals(_root, value))
 8                 {
 9                     _root = value;
10                     RaisePropertyChanged("Root");
11 
12                 }
13 
14             }
15         }

先加载父级节点,对于每个节点添加loading子节点,那样展开节点时就会先显示loading节点,当获取到数据时再加载数据:

 1 private void LoadData()
 2         {
 3             this.Root = new ObservableCollection<Tree<Product>>();
 4             Root.Add(new Tree<Product>(BuildLoadingChild()));
 5 
 6             lstProduct = 获取数据;
 7 
 8             this.Root.Clear();
 9             foreach (Product item in lstProduct )
10             {
11                 Root.Add(new Tree<Product>(item, BuildLoadingChild()));
12 
13             }
14         }
15 
16         private Product BuildLoadingChild()
17         {
18             return new Product()
19             {
20                 ProductId = -999,
21                 ProductName = "loading"
22             };
23         }

展开节点时获取子节点,当然不能忘记先要把loading节点给删掉,先在ViewModel中定义RelayCommand:

 1 private RelayCommand<Tree<Product>> _itemExpanded;
 2         public RelayCommand<Tree<Product>> ItemExpanded
 3         {
 4             get
 5             {
 6                 if (_itemExpanded == null)
 7                 {
 8                     _itemExpanded = new RelayCommand<Tree<Product>>(o => this.OnItemExpanded(o));
 9                 }
10                 return _itemExpanded;
11             }
12         }

展开事件:

 1 private void OnItemExpanded(Tree<Product> item)
 2         {
 3             var lstChildren = 获取数据;
 4             if (lstChildren == null || lstChildren.Count <= 0)
 5             {
 6                 item.Children.Clear();
 7                 return;
 8             }
 9 
10 
11             item.Children.Clear();
12             foreach (Product i in lstChildren)
13             {
14                 item.Children.Add(new Tree<Product>(i, BuildLoadingChild()));
15             }
16         }

 

 

posted @ 2013-01-07 11:03  鳳梨酥  阅读(1166)  评论(0编辑  收藏  举报