当前位置: 首页 > news >正文

WPF 教程:给 TreeView 添加 SelectedItem 双向绑定支持(MVVM-Friendly)

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

相关文章:

  • 全球市场舆情收集:OgPhone云手机如何帮出海企业抢占先机?
  • 【群智能算法改进】一种改进的蜣螂优化算法IDBO[3](立方混沌映射Cubic、融合鱼鹰勘探策略、混合高斯柯西变异)【Matlab代码#92】
  • HarmonyOS:ComposeTitleBar 组件自学指南
  • 【学习笔记】计算机网络(五)
  • 【Golang】Windows系统键鼠空闲监测练习
  • 每天学一个 Linux 命令(8):ls
  • 使用 KT-Connect 0.3.7在本地访问 Kubernetes
  • 如何实现口型0误差?
  • RTL8304问题
  • 《电容:时空交错的能量银行》
  • 愚人杯-web-被遗忘的反序列化
  • [数学]关于组合数
  • 蓝桥杯比赛python程序设计——班级活动
  • 【前端】一文掌握 Vue 3 指令用法(vue3 备忘清单)
  • 字符串复习
  • scss报错Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0
  • 如何加强 SSH 安全:内网和专用网络环境下的防护策略
  • Linux中的文件寻址
  • 脚手架 + 指令
  • 山东大学软件学院项目创新实训开发日志(4)之中医知识问答数据存储、功能结构、用户界面初步设计
  • 长沙制作网站的公司/域名注册信息查询
  • wordpress 邮件内容/安徽网站关键字优化
  • 天津市城市建设档案馆网站/seo具体seo怎么优化
  • 网站域名到期后不续费会怎样/seo官网优化
  • 创新的成都 网站建设/设计网站接单
  • iframe wordpress/电商中seo是什么意思