介绍

我有一种情况,我希望能够将项目添加到列表中,并在列表中移动项目,这似乎是使用a的最简单方法ListBox。我立刻想到了如何以通用的方式做到这一点,然后,也许,可以使用行为来做到这一点。这似乎是一个非常有用的想法。我决定以一种简单的方式为我正在开发的应用程序做这件事,但我想我会创建一个演示项目来探索这个想法。这是结果。

概观

该行为实际上有四个独立的部分,可以在一个类中执行不同的功能:

  • 添加项目
  • 将所选项目向上移动一个位置
  • 将所选项目向下移动一个位置
  • 删除所选项目。

每个函数的代码结构非常相似,只有一些细节不同。

将要检查的代码是Move Up函数的代码。

首先是以下定义DependencyProperty

隐藏   复制代码
public static readonly DependencyProperty MoveItemUpProperty =DependencyProperty.RegisterAttached("MoveItemUp",typeof(Selector), typeof(ListHelperBehavior), new PropertyMetadata(null, OnMoveItemUpChanged)); public static Selector GetMoveItemUp(UIElement uiElement) { return (Selector)uiElement.GetValue(MoveItemUpProperty); } public static void SetMoveItemUp(UIElement uiElement, Selector value) { uiElement.SetValue(MoveItemUpProperty, value); } 

这用于为包含列表的Selector(或ListBox)控件提供绑定。它用于Button执行动作,在这种情况下是将所选项目向上移动一个位置。对于这个动作的代码需要有机会获得ItemsSourceSelectedIndexSelector控制,首先要真正能够做到移动,第二知道要移动的项目。

对于所有操作,此代码几乎相同,只是Add Item不需要监视SelectionChanged事件Selector,并且Button永远不会禁用。

当此DependencyProperty更改时,将OnMoveUpItemChanged执行事件处理程序。此事件处理程序在DependencyPropertyRegisterAttached方法的FrameworkMetadata参数中指定。

隐藏   复制代码
private static void OnMoveItemUpChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{if (e.OldValue is Selector Selector1){Selector1.SelectionChanged -= SetMoveItemUpButtonIsEnabled;}if (e.NewValue is Selector Selector){var Button = CheckForButtonBase(d); Button.Click -= MoveItemUpEvent; Button.Click += MoveItemUpEvent; Selector.SetValue(MoveUpButton, Button); Selector.SelectionChanged += SetMoveItemUpButtonIsEnabled; SetMoveItemUpButtonIsEnabled(Selector, null); } } 

此代码将事件处理程序附加到ButtonClick事件和Selector SelectionChanged事件。为了确保Button在订阅事件之前没有双重订阅Click事件,并且删除SelectionChanged旧事件的事件处理程序Selector(如果存在)。此外,Button它保存在附件DependencyProperty中,Selector以便可以找到它以供SelectionChanged事件处理程序使用。最后,Button通过使用SelectionChanged事件处理程序调整IsEnabled值。

为的保存代码ButtonSelector被下面的私人DependencyProperty从而使Button被启用和禁用,可以发现:

隐藏   复制代码
private static readonly DependencyProperty MoveUpButton =DependencyProperty.RegisterAttached("MoveUpButton",typeof(ButtonBase), typeof(ListHelperBehavior), new PropertyMetadata(null)); 

Add Item代码不需要监视SelectionChanged事件,因为Button从不禁用它。
的Click事件Button下移功能如下:

隐藏   复制代码
private static void MoveItemUpEvent(object sender, RoutedEventArgs e)
{Debug.Assert(sender is ButtonBase);var Button = (ButtonBase)sender;var Selector = GetMoveItemUp(Button);var IList = CheckForIList(Selector); var itemNumber = Selector.SelectedIndex; var item = IList[itemNumber]; IList.RemoveAt(itemNumber); var type = IList.GetType().GetGenericArguments().Single(); var castInstance = Convert.ChangeType(item, type); IList.Insert(itemNumber - 1, castInstance); if (itemNumber == 1) Button.IsEnabled = false; Selector.SelectedIndex = itemNumber - 1; } 

sender参数必须强制转换为ButtonBase类型,然后用于获取Selector作为ButtonBase中附加属性保存的控件的值。然后使用它来获取IList绑定到Selector ItemsSource DependencyPropertySelectedItem值和值SelectorIList然后复制所选项目,转换为正确的类型(使用Type类的Reflection GetGenericArgument方法获取类型,然后使用Convert.ChangeType方法将其强制转换),然后从IList(RemoveAt方法)中删除IList)。然后使用该Selector Insert方法插入删除的项目。

接下来检查是否现在是第一个项目,禁用Button它是否为,并且Selector SelectedIndex设置为仍然指向同一个项目。

码几乎是相同的,则删除要简单得多,因为它没有保存已删除的项目,然后将其放回IList

最后,有适当的代码启用或禁用Button取决于是否存在SelectedItemSelectedItem是第一个(用于上)或最后一个项目IList(用于下移)。这是SelectedItemSelector触发事件时调用的事件处理程序:

隐藏   复制代码
private static void SetMoveItemUpButtonIsEnabled(object sender, RoutedEventArgs e){<code>    Debug.Assert(sender is Selector);var Selector = (Selector)sender;var IList = CheckForIList(Selector);var itemNumber = Selector.SelectedIndex; var Button = (ButtonBase) Selector.GetValue(MoveUpButton); Button.IsEnabled = (itemNumber >= 1 && itemNumber < IList.Count); }</code> 

对于这种需要IList绑定到ItemsSourceSelectedIndex,并需要得到Button保存为一个附加属性在此功能Selector。对于Remove函数,只需要知道if SelectedIndex是否等于-1,这样简单得多。

使用行为

要使用此行为,只需要一个从Selector控件派生的列表控件,Name为此控件关联一个值,并Button为每个应该实现的函数定义一个网站源码。在每一个Button XAML只包括ListHelperBahaviorDependencyProperty它有关联BindingSelector

隐藏   收缩    复制代码
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ListBox Name="TheList"              ItemsSource="{Binding List}"              HorizontalAlignment="Stretch"              VerticalAlignment="Stretch"  > <ListBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition Width="200"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding ItemNumber}"/> <TextBlock Grid.Column="1"                                Text="{Binding TimeCreated}"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <StackPanel Grid.Row="2"                 Margin="-5 5"                 Orientation="Horizontal"                 

转载于:https://www.cnblogs.com/langda/p/10473467.html

WPF开发为按钮提供添加,删除和重新排列ListBox内容的功能相关推荐

  1. mds部署服务器系统,CephFS提供/添加/删除MDS

    部署元数据服务器 每个CephFS文件系统至少需要一个MDS,集群维护者通常会根据需要使用其自动部署工具来启动所需的MDS服务器.推荐使用Rook和ansible(通过ceph-ansible剧本)进 ...

  2. wps启用编辑按钮在哪里_如何在wps工具栏中添加按钮 如何在Excel中添加删除命令按钮...

    延伸:如何在Excel中添加删除命令按钮 描述:在Excel 2003中,很多常用的命令按钮都放置在工具栏中,用户可以很方便地进行操作.添加命令主要是通过拖动的方式完成的,其具体的操作如下:骤一,在视 ...

  3. Three.js中实现点击按钮添加删除旋转立方体

    场景 Three.js中引入dat.gui库实现界面组件控制动画速度变量: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1193 ...

  4. python测试开发django-124.bootstrap点删除按钮弹确认删除

    前言 批量删除bootstrap-table数据,需先弹出确认删除框,提醒用户是否确定删除. 点确定按钮的时候需获取到table表格中选中的数据id数据. 确认删除 期望实现的效果,选中一行或多行可以 ...

  5. Repeater控件中添加删除修改按钮

    1: <asp:LinkButton ID="LinkButton1" runat="server" CommandArgument='<%#Eva ...

  6. WPF开发的实用小工具 - 快捷悬浮菜单

    WPF开发的实用小工具 - 快捷悬浮菜单 ❝ 本文由网友投稿,Dotnet9站长整理.站长觉得这小工具很实用,站长家里.公司也在尝试使用了. 行文目录: 这工具有什么用? 正文 源码获取及应用下载体验 ...

  7. WPF开发必备--类库

    1.XamlFlair XamlFlair 库的目标是简化常见动画的实现,并允许开发人员使用几行 Xaml 轻松添加单个或组合的动画集. Github:https://github.com/XamlF ...

  8. WPF开发学生信息管理系统【WPF+Prism+MAH+WebApi】(完)

    最近通过WPF开发项目,为了对WPF知识点进行总结,所以利用业余时间,开发一个学生信息管理系统[Student Information Management System].前四篇文章进行了框架搭建和 ...

  9. wpf 点击按钮弹出新对话框_wpf弹出输入对话框

    (WINDOWPLACEMENT); wp.flags=WPF_RESTORET... 菜单项,打开新建项目对话框如图1.1. 在模板(T) 列表框中选择Windows窗体应用程序 ,在名称(N) 编 ...

最新文章

  1. 介绍三种绘制时间线图的方法
  2. 独家 | 手把手教你用Python构建你的第一个多标签图像分类模型(附案例)
  3. 用 PHP 和 MySQL 保存和输出图片
  4. js 的数值限制可能引起的问题
  5. Windows Server 2008服务器管理新技巧6则第1/4页
  6. Your WebGL implementation doesn't seem to support hardware accelerated rendering. Check your browser
  7. MyEclipse、eclipse代码自动补全
  8. 为什么 HTTPS 是安全的?
  9. 经常使用Log日志打印输出
  10. 《Windows Communication Foundation之旅》系列之二
  11. 文档词频矩阵_论文理解:从词嵌入到文档距离
  12. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题HIL
  13. Linux 系统级开启文件句柄 调优
  14. 值得收藏的资源网站大全
  15. 解决了Office2007向程序发送命令时出现错误 的问题
  16. C语言利用差分法求解泊松方程
  17. python中forward的参数_ip_forward参数对Linux内核转发影响分析
  18. 0085 开头的电话拦截方法(小米手机有效)
  19. NmapToExcel 批量nmap写入xlsx
  20. 九段刀客:Windows下配置Jenkins自动打包vue

热门文章

  1. 见过一个一个拉新地推没见过这么多一起推
  2. 没有上市的股权和股票有啥区别
  3. 过去几年的互联网经济,首先是“免费经济”
  4. 你想过同时为两家以上的企业工作吗?
  5. 那些月入1万的自媒体大咖,惯用的4个爆款选题分享给你
  6. mac文件丢失,苹果电脑有没有好用的恢复软件?
  7. Qt4_中央窗口部件
  8. azure云数据库_Azure SQL数据库地理复制
  9. Linux上SQL Server合并复制
  10. 如何解决SQL Server中SQL身份危机