您应该使用 TreeView 的 ItemContainer 样式。
这是示例 TreeNode 视图模型:
public class TreeNode : ViewModel
{
public TreeNode()
{
this.children = new ObservableCollection<TreeNode>();
// the magic goes here
this.addChildCommand = new RelayCommand(obj => AddNewChild());
}
private void AddNewChild()
{
// create new child instance
var child = new TreeNode
{
Name = "This is a new child node.",
IsSelected = true // new child should be selected
};
// add it to collection
children.Add(child);
// expand this node, we want to look at the new child node
IsExpanded = true;
}
public String Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
OnPropertyChanged("Name");
}
}
}
private String name;
public Boolean IsSelected
{
get { return isSelected; }
set
{
if (isSelected != value)
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
private Boolean isSelected;
public Boolean IsExpanded
{
get { return isExpanded; }
set
{
if (isExpanded != value)
{
isExpanded = value;
OnPropertyChanged("IsExpanded");
}
}
}
private Boolean isExpanded;
public ObservableCollection<TreeNode> Children
{
get { return children; }
}
private ObservableCollection<TreeNode> children;
public ICommand AddChildCommand
{
get { return addChildCommand; }
}
private RelayCommand addChildCommand;
}
一些评论:
- ViewModel 是 INotifyPropertyChanged 接口的任何基本实现。
- RelayCommand(又名 DelegateCommand)是用于 MVVM 方法的 ICommand 实现。
这是视图:
<Window x:Class="WpfApplication1.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">
<TreeView ItemsSource="{Binding}">
<TreeView.ItemContainerStyle>
<!-- Let's glue our view models with the view! -->
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<!-- Here's menu item, which is responsible for adding new child node -->
<MenuItem Header="Add child..." Command="{Binding AddChildCommand}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
...和示例数据上下文初始化:
public MainWindow()
{
InitializeComponent();
DataContext = new ObservableCollection<TreeNode>
{
new TreeNode { Name = "Root", IsSelected = true }
};
}
希望这可以帮助。
更新。
当然,您也必须将子节点公开为 ObservableCollection。否则,对节点集合所做的更改将不会反映。