wpf Behaviors库实现支持多选操作进行后台绑定数据的ListView

请添加图片描述

 <ListView ItemsSource="{Binding SchemeItems}" SelectionMode="Extended"   VerticalAlignment="Stretch" HorizontalAlignment="Stretch"><ListView.ContextMenu><ContextMenu><MenuItem Header="删除" Command="{Binding DeleteSelectedItemCommand}"/></ContextMenu></ListView.ContextMenu><i:Interaction.Behaviors><behaviors:SelectedItemsBehavior SelectedItems="{Binding SelectedSchemeItems, Mode=TwoWay}"/></i:Interaction.Behaviors><ListView.View><GridView><GridViewColumn Header="方案名"  DisplayMemberBinding="{Binding Name}"/></GridView></ListView.View></ListView>

1. ListView控件的定义

<ListView ItemsSource="{Binding SchemeItems}" SelectionMode="Extended" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
  • ItemsSource="{Binding SchemeItems}"
    • 这是数据绑定的属性,表示ListView的数据源绑定到视图模型(ViewModel)中的SchemeItems属性。
    • SchemeItems应该是一个集合类型(如ObservableCollection),其中存储了要显示在ListView中的数据项。
  • SelectionMode="Extended"
    • 设置ListView的选中模式为“扩展模式”,允许用户通过按下CtrlShift键选择多个项目。
  • VerticalAlignment="Stretch"HorizontalAlignment="Stretch"
    • 这两个属性设置ListView在父容器中垂直和水平方向上拉伸以填充可用空间。

2. 上下文菜单(ContextMenu

<ListView.ContextMenu><ContextMenu><MenuItem Header="删除" Command="{Binding DeleteSelectedItemCommand}"/></ContextMenu>
</ListView.ContextMenu>
  • ContextMenu
    • 定义了ListView的上下文菜单,即用户右键单击ListView时显示的菜单。
  • MenuItem Header="删除" Command="{Binding DeleteSelectedItemCommand}"
    • 定义了一个菜单项,标题为“删除”。
    • Command="{Binding DeleteSelectedItemCommand}"
      • 绑定了一个命令,当用户点击“删除”菜单项时,会触发视图模型中的DeleteSelectedItemCommand命令。
      • 这个命令通常用于删除选中的项目。

3. 行为(Interaction.Behaviors

<i:Interaction.Behaviors><behaviors:SelectedItemsBehavior SelectedItems="{Binding SelectedSchemeItems, Mode=TwoWay}"/>
</i:Interaction.Behaviors>
  • Interaction.Behaviors
    • 使用了System.Windows.Interactivity命名空间(通常通过xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"引入)来添加行为。
  • behaviors:SelectedItemsBehavior
    • 这是一个自定义行为,可能是为了处理ListView的多选项目。
  • SelectedItems="{Binding SelectedSchemeItems, Mode=TwoWay}"
    • 将行为的SelectedItems属性与视图模型中的SelectedSchemeItems属性进行双向绑定。
    • 这样,当用户在ListView中选择项目时,SelectedSchemeItems会自动更新,反之亦然。

4. ListView的视图(ListView.View

<ListView.View><GridView><GridViewColumn Header="方案名" DisplayMemberBinding="{Binding Name}"/></GridView>
</ListView.View>
  • ListView.View
    • 定义了ListView的显示方式,这里使用了GridView,即表格视图。
  • GridViewColumn Header="方案名" DisplayMemberBinding="{Binding Name}"
    • 定义了一个表格列,标题为“方案名”。
    • DisplayMemberBinding="{Binding Name}"
      • 表示该列显示的数据项的Name属性值。
      • 假设SchemeItems集合中的每个项目都有一个Name属性,那么这个属性的值将显示在该列中。
public class SelectedItemsBehavior : Behavior<ListView>
{public static readonly DependencyProperty SelectedItemsProperty =DependencyProperty.Register(nameof(SelectedItems),typeof(ObservableCollection<SchemeItem>),typeof(SelectedItemsBehavior),new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));public ObservableCollection<SchemeItem> SelectedItems{get => (ObservableCollection<SchemeItem>)GetValue(SelectedItemsProperty);set => SetValue(SelectedItemsProperty, value);}protected override void OnAttached(){base.OnAttached();AssociatedObject.SelectionChanged += OnSelectionChanged;}protected override void OnDetaching(){AssociatedObject.SelectionChanged -= OnSelectionChanged;base.OnDetaching();}private void OnSelectionChanged(object sender, SelectionChangedEventArgs e){SelectedItems = new ObservableCollection<SchemeItem>(AssociatedObject.SelectedItems.Cast<SchemeItem>());}
}

下面代码定义了一个名为SelectedItemsBehavior的行为类,用于扩展ListView的功能,特别是处理多选项目并将其与视图模型绑定:

1. 类定义

public class SelectedItemsBehavior : Behavior<ListView>
  • Behavior<ListView>
    • 这是一个从System.Windows.Interactivity.Behavior<T>继承的类,专门用于为ListView控件添加行为。
    • Behavior<T>是WPF中用于扩展控件功能的机制,允许开发者通过附加行为来增强控件的功能,而无需修改控件本身的代码。

2. 依赖属性(DependencyProperty

public static readonly DependencyProperty SelectedItemsProperty =DependencyProperty.Register(nameof(SelectedItems),typeof(ObservableCollection<SchemeItem>),typeof(SelectedItemsBehavior),new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
  • DependencyProperty.Register
    • 定义了一个名为SelectedItemsProperty的依赖属性,用于存储选中的项目集合。
    • nameof(SelectedItems):属性的名称。
    • typeof(ObservableCollection<SchemeItem>):属性的类型,表示选中的项目是一个ObservableCollection<SchemeItem>集合。
    • typeof(SelectedItemsBehavior):依赖属性所属的类。
    • FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
      • 设置了默认值为null
      • 设置了BindsTwoWayByDefault选项,表示该属性默认支持双向绑定。

3. SelectedItems属性

public ObservableCollection<SchemeItem> SelectedItems
{get => (ObservableCollection<SchemeItem>)GetValue(SelectedItemsProperty);set => SetValue(SelectedItemsProperty, value);
}
  • 这是一个包装了SelectedItemsProperty依赖属性的CLR属性。
  • 通过GetValueSetValue方法,可以方便地获取和设置SelectedItemsProperty的值。

4. 附加行为(OnAttached

protected override void OnAttached()
{base.OnAttached();AssociatedObject.SelectionChanged += OnSelectionChanged;
}
  • OnAttached
    • 当行为被附加到ListView控件时,会调用此方法。
    • AssociatedObject
      • 表示行为所附加的控件,在这里是ListView
    • AssociatedObject.SelectionChanged += OnSelectionChanged
      • 订阅了ListViewSelectionChanged事件,当ListView的选中项发生变化时,会触发OnSelectionChanged方法。

5. 分离行为(OnDetaching

protected override void OnDetaching()
{AssociatedObject.SelectionChanged -= OnSelectionChanged;base.OnDetaching();
}
  • OnDetaching
    • 当行为从ListView控件分离时,会调用此方法。
    • AssociatedObject.SelectionChanged -= OnSelectionChanged
      • 取消订阅SelectionChanged事件,以避免内存泄漏。

6. 处理选中项变化(OnSelectionChanged

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{SelectedItems = new ObservableCollection<SchemeItem>(AssociatedObject.SelectedItems.Cast<SchemeItem>());
}
  • OnSelectionChanged
    • ListView的选中项发生变化时,此方法会被触发。
    • AssociatedObject.SelectedItems
      • 获取ListView当前选中的项目集合。
    • Cast<SchemeItem>()
      • 将选中的项目集合转换为SchemeItem类型的集合。
    • new ObservableCollection<SchemeItem>(...)
      • 创建一个新的ObservableCollection<SchemeItem>实例,并将其赋值给SelectedItems属性。
      • 这样,SelectedItems属性会实时更新,反映当前ListView的选中项。

总结

SelectedItemsBehavior类的作用是:

  1. 扩展ListView的功能
    • 通过行为机制,为ListView添加了对多选项目的支持,并将其与视图模型中的ObservableCollection<SchemeItem>属性进行双向绑定。
  2. 自动更新选中项
    • 当用户在ListView中选择或取消选择项目时,SelectedItems属性会自动更新,确保视图模型中的数据与用户界面保持一致。

通过在XAML中使用<behaviors:SelectedItemsBehavior SelectedItems="{Binding SelectedSchemeItems, Mode=TwoWay}"/>,可以将ListView的选中项与视图模型中的SelectedSchemeItems属性绑定,实现数据的双向同步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

50个JAVA常见代码大全:学完这篇从Java小白到架构师

50个JAVA常见代码大全&#xff1a;学完这篇从Java小白到架构师 Java&#xff0c;作为一门流行多年的编程语言&#xff0c;始终占据着软件开发领域的重要位置。无论是初学者还是经验丰富的程序员&#xff0c;掌握Java中常见的代码和概念都是至关重要的。本文将列出50个Java常用…

【Linux手册】冯诺依曼体系结构

目录 前言 五大组件 数据信号 存储器&#xff08;内存&#xff09;有必要吗 常见面试题 前言 冯诺依曼体系结构是当代计算机基本架构&#xff0c;冯诺依曼体系有五大组件&#xff0c;通过这五大组件直观的描述了计算机的工作原理&#xff1b;学习冯诺依曼体系可以让给我们更…

10_聚类

描述 聚类&#xff08;clustering&#xff09;是将数据集划分成组的任务&#xff0c;这些组叫作簇&#xff08;cluster&#xff09;。其目标是划分数据&#xff0c;使得一个簇内的数据点非常相似且不同簇内的数据点非常不同。与分类算法类似&#xff0c;聚类算法为每个数据点分…

【SSM】SpringBoot学习笔记1:SpringBoot快速入门

前言&#xff1a; 文章是系列学习笔记第9篇。基于黑马程序员课程完成&#xff0c;是笔者的学习笔记与心得总结&#xff0c;供自己和他人参考。笔记大部分是对黑马视频的归纳&#xff0c;少部分自己的理解&#xff0c;微量ai解释的内容&#xff08;ai部分会标出&#xff09;。 …

国产高性能pSRAM选型指南:CSS6404LS-LI 64Mb QSPI伪静态存储器

一、芯片基础特性 核心参数 容量 &#xff1a;64Mb&#xff08;8M 8bit&#xff09;电压 &#xff1a;单电源供电 2.7-3.6V &#xff08;兼容3.3V系统&#xff09;接口 &#xff1a;Quad-SPI&#xff08;QPI/SPI&#xff09;同步模式封装 &#xff1a; SOP-8L (150mil) &#…

Cilium动手实验室: 精通之旅---4.Cilium Gateway API - Lab

Cilium动手实验室: 精通之旅---4.Cilium Gateway API - Lab 1. 环境准备2. API 网关--HTTP2.1 部署应用2.2 部署网关2.3 HTTP路径匹配2.4 HTTP头匹配 3. API网关--HTTPS3.1 创建TLS证书和私钥3.2 部署HTTPS网关3.3 HTTPS请求测试 4. API网关--TLS 路由4.1 部署应用4.2 部署网关…

20250605在微星X99主板中配置WIN10和ubuntu22.04.6双系统启动的引导设置

rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair rootrootrootroot-X99-Turbo:~$ sudo add-apt-repository ppa:yannubuntu/boot-repair rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair 20250605在微星X99主板中配置WIN10和ubuntu22.04.6双…

MyBatis之测试添加功能

1. 首先Mybatis为我们提供了一个操作数据库的会话对象叫Sqlsession&#xff0c;所以我们就需要先获取sqlsession对象&#xff1a; //加载核心配置文件 InputStream is Resources.getResourceAsStream("mybatis-config.xml"); //获取sqlSessionFactoryBuilder(是我…

[论文阅读] 人工智能+软件工程 | MemFL:给大模型装上“项目记忆”,让软件故障定位又快又准

【论文解读】MemFL&#xff1a;给大模型装上“项目记忆”&#xff0c;让软件故障定位又快又准 论文信息 arXiv:2506.03585 Improving LLM-Based Fault Localization with External Memory and Project Context Inseok Yeo, Duksan Ryu, Jongmoon Baik Subjects: Software Engi…

Java开发中复用公共SQL的方法

在一次Java后端开发的面试中&#xff0c;面试官问了我一个问题&#xff1a;“你在写代码时会复用公共SQL吗&#xff1f;如果会的话&#xff0c;能详细介绍一下你是如何实现的吗&#xff1f;”这个问题让我眼前一亮&#xff0c;因为在实际项目中&#xff0c;SQL复用确实是一个非…

C#学习26天:内存优化的几种方法

1.减少对象创建 使用场景&#xff1a; 在循环或密集计算中频繁创建对象时。涉及大量短生命周期对象的场景&#xff0c;比如日志记录或字符串拼接。游戏开发中&#xff0c;需要频繁更新对象状态时。 说明&#xff1a; 重用对象可以降低内存分配和垃圾回收的开销。使用对象池…

【opencv】基础知识到进阶(更新中)

安装&#xff1a;pip install opencv-python 入门案例 读取图片 本节我们将来学习,如何使用opencv显示一张图片出来,我们首先需要掌握一条图片读取的api cv.imread("图片路径","读取的方式") # 图片路径: 需要在工程目录中,或者一个文件的绝对路径 # 读取…

【Part 3 Unity VR眼镜端播放器开发与优化】第二节|VR眼镜端的开发适配与交互设计

文章目录 《VR 360全景视频开发》专栏Part 3&#xff5c;Unity VR眼镜端播放器开发与优化第一节&#xff5c;基于Unity的360全景视频播放实现方案第二节&#xff5c;VR眼镜端的开发适配与交互设计一、Unity XR开发环境与设备适配1.1 启用XR Plugin Management1.2 配置OpenXR与平…

SQL进阶之旅 Day 16:特定数据库引擎高级特性

【SQL进阶之旅 Day 16】特定数据库引擎高级特性 开篇 在“SQL进阶之旅”系列的第16天&#xff0c;我们将探讨特定数据库引擎的高级特性。这些特性通常为某些特定场景设计&#xff0c;能够显著提升查询性能或简化复杂任务。本篇文章将覆盖MySQL、PostgreSQL和Oracle的核心高级…

c++算法学习4——广度搜索bfs

一、引言&#xff1a;探索迷宫的智能方法 在解决迷宫最短路径问题时&#xff0c;广度优先搜索&#xff08;BFS&#xff09;是一种高效而优雅的算法。与深度优先搜索&#xff08;DFS&#xff09;不同&#xff0c;BFS采用"由近及远"的搜索策略&#xff0c;逐层探索所有…

4.RV1126-OPENCV 图像轮廓识别

一.图像识别API 1.图像识别作用 它常用于视觉任务、目标检测、图像分割等等。在 OPENCV 中通常使用 Canny 函数、findContours 函数、drawContours 函数结合在一起去做轮廓的形检测。 2.常用的API findContours 函数&#xff1a;用于寻找图片的轮廓&#xff0c;并把所有的数…

Qt多线程访问同一个数据库源码分享(基于Sqlite实现)

Qt多线程访问同一个数据库源码分享&#xff08;基于Sqlite实现&#xff09; 一、实现难点线程安全问题死锁风险连接管理问题数据一致性性能瓶颈跨线程信号槽最佳实践建议 二、源码分享三、测试1、新建一个多线程类2、开启多线程插入数据 一、实现难点 多线程环境下多个线程同时…

双空间知识蒸馏用于大语言模型

Dual-Space Knowledge Distillation for Large Language Models 发表&#xff1a;EMNLP 2024 机构&#xff1a;Beijing Key Lab of Traffic Data Analysis and Mining 连接&#xff1a;https://aclanthology.org/2024.emnlp-main.1010.pdf 代码&#xff1a;GitHub - songmz…

贪心算法应用:多重背包启发式问题详解

贪心算法应用&#xff1a;多重背包启发式问题详解 多重背包问题是经典的组合优化问题&#xff0c;也是贪心算法的重要应用场景。本文将全面深入地探讨Java中如何利用贪心算法解决多重背包问题。 多重背包问题定义 **多重背包问题(Multiple Knapsack Problem)**是背包问题的变…

ES6 Promise 状态机

状态机&#xff1a;抽象的计算模型&#xff0c;根据特定的条件或者信号切换不同的状态 一、Promise 是什么&#xff1f; 简单来说&#xff0c;Promise 就是一个“承诺对象”。在ES6 里&#xff0c;有些代码执行起来需要点时间&#xff0c;比如加载文件、等待网络请求或者设置…