一、ListBox中为什么选择同一项不能每次都触发SelectionChanged事件呢?

​ 当我需要每次点击ListBox的选中项,都触发事件。找到最符合的事件为SelectionChanged事件。但使用SelectionChanged事件时,并不能每次都触发。

​ 这是因为SelectionChanged事件是选中项发生变化时才会触发,如果上次选中与本次相同,则单击是不会触发SelectionChanged事件。

二、使用附加属性声明 ICommand

我们可以使用附加属性声明一个ICommand解决以上问题。具体步骤如下:

(1)声明一个附加属性。

    class AttachedLib
{
public static ICommand GetClick(DependencyObject obj)
{
return (ICommand)obj.GetValue(ClickProperty);
} public static void SetClick(DependencyObject obj, ICommand value)
{
obj.SetValue(ClickProperty, value);
} // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ClickProperty =
DependencyProperty.RegisterAttached("Click", typeof(ICommand), typeof(AttachedLib), new PropertyMetadata(null));
}

(2)将该附加属性添加到ListBox上,并绑定待实现的ICommand。

  <Grid>
<ListBox Margin="10"
ItemsSource="{Binding StudentCollection}"
ItemTemplate="{StaticResource StudentTemplate}"
local:AttachedLib.Click="{Binding SelectCommand}"></ListBox>
</Grid>
       public ICommand SelectCommand { get; set; }

        private void ExecuteSelectCommand(object obj)
{
if (obj is Student student)
{
MessageBox.Show($"{student.Id},{student.Name},{student.Age}","选中的学生信息");
}
} public MainWindowVM()
{
StudentCollection = new ObservableCollection<Student>()
{
new Student(){Id = 1,Name = "Dwayne", Age = 10,},
new Student(){Id = 2,Name = "John", Age = 11,},
new Student(){Id = 3,Name = "Aaron", Age = 12,},
};
SelectCommand=new RelayCommand(ExecuteSelectCommand);
}

(3)在ListBox的ListBoxItem模板中,添加一个Button,Button的Command使用相对路径绑定该附加属性。

 <DataTemplate x:Key="StudentTemplate" DataType="{x:Type local:Student}">
<Button BorderThickness="0"
Background="Transparent"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}, Path=(local:AttachedLib.Click)}"
CommandParameter="{Binding}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10,5" Width="100" Text="{Binding Id}"></TextBlock>
<TextBlock Margin="10,5" Width="200" Text="{Binding Name}"></TextBlock>
<TextBlock Margin="10,5" Width="100" Text="{Binding Age}"></TextBlock>
</StackPanel>
</Button>
</DataTemplate>

三、总结

通过以上操作,由Button触发单击事件,就可以实现”每次点击ListBox的选中项,都触发事件“的预期目标。

WPF 使用附加属性声明 ICommand的更多相关文章

  1. WPF通过附加属性控制窗口关闭

    场景1 当使用 ShowDialog() 方式显示窗口时,通过定义附加属性的方式可实现在 ViewModel 中进行数据绑定(bool?)来控制子窗口的显示和关闭 public class ExWin ...

  2. WPF Adorner+附加属性 实现控件友好提示

    标题太空泛,直接上图 无论是在验证啊,还是提示方面等一些右上角的角标之类的效果,我们会怎么做? 这里介绍一种稍微简单一些的方法,利用附加属性和Adorner来完成. 例如WPF自带的控件上要加这样的效 ...

  3. WPF利用附加属性修改ShowGridLines效果

    1.思路主要代码 wpf的gridline原本效果是虚线类型的.有时候需要设计成表格形式的,因此有了用附加属性来自动绘制边框线的想法. 思路:绘制Line并添加到grid的children里,但效果并 ...

  4. WPF使用附加属性绑定,解决data grid列绑定不上的问题

    背景 需要对datagrid的列header添加自定义属性,然后绑定,并根据不同的列header绑定不同的值,传统的加扩展类太麻烦,而附加属性的特点更适用于这种场景. 1.xaml 代码 <Da ...

  5. 【WPF】附加属性

    一直都对附加属性理解很模糊,今天看了一篇文章,恍然大悟,用个Demo掩饰一下对附加属性的理解 附加属性,简单的理解就是给一个对象外在的定义一个属性,使得该对象拥有和使用该属性,最典型的是Grid.Ro ...

  6. WPF 使用附加属性增加控件属性

    使用附加属性增加控件属性,使得这个附加属性在使用的时候没有局限性,可以在任何的控件中使用它来增加所需要的属性,使得控件的属性使用起来非常灵活 一.自定义附加属性 using System; using ...

  7. (WPF)附加属性

    <Window x:Class="DeepXAML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...

  8. WPF 依赖附加属性

    附加属性的本质是一个依赖属性,与普通的依赖属性区别: 1:注册方法名不一样,如 DependencyProperty.RegisterAttached 2:没有普通的属性包装器,而是通过get和set ...

  9. 【2016-11-11】【坚持学习】【Day24】【WPF 自定义控件 附加属性 自定义事件】

    UserControl ,自定义控件. 这里刚刚想到一个问题.什么时候应该用usercontrol 定义一个控件.什么时候应该重写控件的template和样式,实现新效果. 引用一下人家的话:http ...

随机推荐

  1. 【LiteOS】LiteOS消息队列

    目录 前言 链接 参考 笔录草稿 基本概念 队列运作机制 队列运作原理 消息队列传输方式 消息队列的阻塞机制 出队阻塞 入队阻塞 任务相关函数 任务开发流程 注意事项 * 实战 前言 链接 LiteO ...

  2. Elasticsearch 分页查询

    目录 前言 from + size search after scroll api 总结 参考资料 前言 我们在实际工作中,有很多分页的需求,商品分页.订单分页等,在MySQL中我们可以使用limit ...

  3. 如何在O(1)时间复杂度获取栈中最大值和最小值

    问题描述: 如何在O(1)时间复杂度获取栈中的最大值和最小值? 问题分析: 普通栈规定的push(入栈).pop(出栈).peek(查看栈顶)等操作都只能在栈顶上操作,如果栈中元素是有序的,那么我们就 ...

  4. Istio 故障注入之延时(fixedDelay)

    Istio 故障注入 Istio 故障注入与其他在网络层引入错误(例如延迟数据包或者直接杀死 Pod)的机制不同,Istio 允许在应用程序层注入故障.这使得可以注入更多相关的故障,比如 HTTP 错 ...

  5. 从HotSpot VM源码看字符串常量池(StringTable)和intern()方法

    引言 字符串常量池(StringTable)是JVM中一个重要的结构,它有助于避免重复创建相同内容的String对象.那么StringTable是怎么实现的?"把字符串加入到字符串常量池中& ...

  6. Python基础(七):字符串的使用(上)

    什么是字符串? 字符串该如何定义呢?通俗的说:字符串就是一系列的字符. 创建字符串的3种方式 单引号创建 >>> a = 'I am a student' >>> ...

  7. Spring 学习笔记(二):SpringIoC

    1 IoC与DI IoC是Inversion of Control的简称,也就是控制反转.通常来说,创建对象需要调用者手动创建,也就是new XXX()的方式.当Spring框架出现后,对象的实例不再 ...

  8. SpringBoot中的自动代码生成 - 基于Mybatis-Plus

    作者:汤圆 个人博客:javalover.cc 前言 大家好啊,我是汤圆,今天给大家带来的是<SpringBoot中的自动代码生成 - 基于Mybatis-Plus>,希望对大家有帮助,谢 ...

  9. .NET6 平台系列4 .NET开源之路

    系列目录     [已更新最新开发文章,点击查看详细] .NET平台是微软于2000年推出的Windows操作系统的应用软件开发框架,发展至今形成巨大的技术栈,涉及多语言(支持C#.F#.VB.NET ...

  10. k8s 创建私有docker仓库 登陆授权令牌的Secret

    参考https://kubernetes.io/zh/docs/tasks/configure-pod-container/pull-image-private-registry/ Kubernete ...