🌲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 應用。