使用wpf写一个treeview 可以自由添加节点,删除,双击等操作,使用mvvm格式
时间: 2024-05-04 10:22:04 浏览: 186
TreeView【WPF节点可以编辑】
4星 · 用户满意度95%
首先,我们需要在ViewModel中定义一个类来表示树节点,例如:
```csharp
public class TreeNodeViewModel : INotifyPropertyChanged
{
private string _text;
private ObservableCollection<TreeNodeViewModel> _children;
public string Text
{
get { return _text; }
set
{
if (_text != value)
{
_text = value;
OnPropertyChanged(nameof(Text));
}
}
}
public ObservableCollection<TreeNodeViewModel> Children
{
get { return _children; }
set
{
if (_children != value)
{
_children = value;
OnPropertyChanged(nameof(Children));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
```
然后,我们在MainViewModel中定义一个ObservableCollection<TreeNodeViewModel>来表示树的根节点,以及一些方法来添加/删除节点和处理双击事件:
```csharp
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<TreeNodeViewModel> _rootNodes;
public ObservableCollection<TreeNodeViewModel> RootNodes
{
get { return _rootNodes; }
set
{
if (_rootNodes != value)
{
_rootNodes = value;
OnPropertyChanged(nameof(RootNodes));
}
}
}
public MainViewModel()
{
RootNodes = new ObservableCollection<TreeNodeViewModel>();
}
public void AddNode(TreeNodeViewModel parent, string text)
{
if (parent == null)
{
RootNodes.Add(new TreeNodeViewModel { Text = text, Children = new ObservableCollection<TreeNodeViewModel>() });
}
else
{
parent.Children.Add(new TreeNodeViewModel { Text = text, Children = new ObservableCollection<TreeNodeViewModel>() });
}
}
public void RemoveNode(TreeNodeViewModel node)
{
if (node == null)
{
return;
}
if (node == RootNodes.FirstOrDefault())
{
RootNodes.Remove(node);
}
else
{
var parent = FindParentNode(RootNodes, node);
if (parent != null)
{
parent.Children.Remove(node);
}
}
}
public void HandleDoubleClick(TreeNodeViewModel node)
{
// handle double click event
}
private TreeNodeViewModel FindParentNode(IEnumerable<TreeNodeViewModel> nodes, TreeNodeViewModel child)
{
foreach (var node in nodes)
{
if (node == child || node.Children == null)
{
continue;
}
if (node.Children.Contains(child))
{
return node;
}
var parent = FindParentNode(node.Children, child);
if (parent != null)
{
return parent;
}
}
return null;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
```
最后,我们可以在View中使用TreeView控件来显示树,并将其绑定到MainViewModel中的RootNodes属性。我们还可以为TreeViewItem添加双击事件处理程序,以及为ContextMenu添加添加/删除节点的菜单项。
```xaml
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Text}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="MouseDoubleClick" Handler="TreeViewItem_DoubleClick" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add Node" Command="{Binding AddNodeCommand}" />
<MenuItem Header="Remove Node" Command="{Binding RemoveNodeCommand}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
```
阅读全文