在开发Silverlight应用程序时,经常会遇到需要通过ViewModel来控制TreeView Control节点展开的情况。本文将介绍如何使用Behavior来实现这一功能,同时避免使用代码后台,以适应那些不具备编程能力的设计师使用Microsoft Expression Blend创建UI的需求。
首先,从TreeView Control的正常操作开始,使用ViewModel(MVVM模式)进行绑定。从一个简单的Category类开始,将Categories集合绑定到TreeView Control上。然后创建一个ICommand,用来设置节点的IsSelected属性。
public ICommand SetCategoryCommand {
get;
set;
}
public void SetCategory(object param) {
foreach (var Cat in colCategory) {
var result = (from objCategory in Cat.AllChildren()
where objCategory.CategoryName == "Category Sub1-1"
select objCategory).FirstOrDefault();
if (result != null) {
result.IsSelected = true;
}
}
}
private bool CanSetCategory(object param) {
return true;
}
然后,可以通过按钮来触发ICommand,从而选中节点上的复选框。但是,如果TreeView Control是折叠状态,即使节点被选中,也无法看到,除非手动展开TreeView节点。
为了解决这个问题,首先在ViewModel中创建一个属性来保存选中节点的值:
private Category _SelectedCategory;
public Category SelectedCategory {
get {
return _SelectedCategory;
}
set {
if (SelectedCategory == value) {
return;
}
_SelectedCategory = value;
this.NotifyPropertyChanged("SelectedCategory");
}
}
接下来,创建一个Behavior并将其放置在TreeView Control上。将按钮设置为触发Behavior,并将SelectedCategory绑定到Behavior上。注意,还有一个ExpandOnLoad复选框,允许指示节点是在页面加载时展开,还是通过事件(如按钮点击)触发。
当运行项目并点击按钮时,TreeView Control的节点将自动展开。Behavior的代码并不复杂,这是主要的工作方法:
private void SelectNode() {
if (SelectedCategory != null) {
objTreeView.UpdateLayout();
MainPageViewModel objMainPageViewModel = (MainPageViewModel)objTreeView.DataContext;
ObservableCollection colCategories = (ObservableCollection)objMainPageViewModel.colCategory;
foreach (var Cat in colCategories) {
var result = (from objCategory in Cat.AllChildren()
where objCategory == SelectedCategory
select objCategory).FirstOrDefault();
if (result != null) {
TreeViewItem objTreeViewItem = (TreeViewItem)objTreeView.ItemContainerGenerator.ContainerFromItem(Cat);
objTreeViewItem.IsExpanded = true;
objTreeView.UpdateLayout();
ExpandChildNode(objTreeViewItem, Cat);
}
}
}
}
这个方法用于展开子节点:
private void ExpandChildNode(TreeViewItem objTreeViewItem, Category Cat) {
foreach (var item in Cat.Categories) {
var result = (from objCategory in item.AllChildren()
where objCategory == SelectedCategory
select objCategory).FirstOrDefault();
if (result != null) {
TreeViewItem SubTreeViewItem = (TreeViewItem)objTreeViewItem.ItemContainerGenerator.ContainerFromItem(item);
SubTreeViewItem.IsExpanded = true;
objTreeView.UpdateLayout();
ExpandChildNode(SubTreeViewItem, item);
}
}
}