🌲WPF 教程:给 TreeView 添加 SelectedItem 双向绑定支持(MVVM-Friendly)
在 WPF 的 MVVM 应用中,TreeView
是非常常见的控件,但它有个“顽固”的缺陷:
❗它的 SelectedItem
不是依赖属性,无法直接绑定到 ViewModel!
这对于追求纯粹 MVVM 架构的开发者来说,很不友好。别担心,本文将教你如何写一个自定义 Behavior
,让 TreeView 也能优雅地绑定 SelectedItem
。
🧠 核心思路
利用 Microsoft.Xaml.Behaviors.Wpf
提供的 Behavior<T>
,监听 TreeView.SelectedItemChanged
事件,并同步绑定到 ViewModel,同时支持反向设置。
🧙♂️ 魔法代码:BindableSelectedItemBehavior.cs
using Microsoft.Xaml.Behaviors;
namespace MVBuilder.Behaviours
{
/// <summary>
/// 让 WPF TreeView 支持 SelectedItem 双向绑定的行为类。
/// 应用于 TreeView 后,可在 ViewModel 中直接使用绑定方式访问/设置选中项。
/// </summary>
public class BindableSelectedItemBehavior : Behavior<TreeView>
{
/// <summary>
/// 可绑定的 SelectedItem 属性(同步 TreeView.SelectedItem)
/// </summary>
public object? SelectedItem
{
get => GetValue(SelectedItemProperty);
set => SetValue(SelectedItemProperty, value);
}
/// <summary>
/// SelectedItem 依赖属性注册
/// </summary>
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
nameof(SelectedItem),
typeof(object),
typeof(BindableSelectedItemBehavior),
new UIPropertyMetadata(null, OnSelectedItemChanged));
/// <summary>
/// 当 SelectedItem 属性变化时,选中对应的 TreeViewItem
/// </summary>
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is TreeViewItem item)
{
item.SetValue(TreeViewItem.IsSelectedProperty, true);
}
}
/// <summary>
/// 附加行为时,注册 TreeView 的 SelectedItemChanged 事件
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
}
/// <summary>
/// 移除行为时,注销事件,避免内存泄漏
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
}
/// <summary>
/// 当 TreeView 选中项变化,更新 SelectedItem 依赖属性(同步到 ViewModel)
/// </summary>
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SetCurrentValue(SelectedItemProperty, e.NewValue);
}
}
}
🧰 NuGet 引用
确保你的项目安装了以下包:
Microsoft.Xaml.Behaviors.Wpf
🔧 使用方式(XAML 示例)
<TreeView ItemsSource="{Binding TreeNodes}" x:Name="tree">
<i:Interaction.Behaviors>
<behaviors:BindableSelectedItemBehavior
SelectedItem="{Binding SelectedNode, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</TreeView>
ViewModel 示例代码
private TreeNodeModel? _selectedNode;
public TreeNodeModel? SelectedNode
{
get => _selectedNode;
set => SetProperty(ref _selectedNode, value);
}
📌 总结一句话
WPF 的 TreeView 不支持绑定 SelectedItem?
没事,我们自己写个 Behavior 就能完美解决!🌟
希望这段小而强的代码能帮你彻底解决 WPF 中 SelectedItem 无法绑定的问题,继续写出纯粹、高质量的 MVVM 应用。