• [WPF]如何正确地用代码设置ListBox的当前选中项


    有人可能会说这有什么好写的。不就是一行代码就能搞定的吗?而且为什么需要用代码设置SelectedItem呢?用户所点的Item不就自动是SelectedItem吗?在这里将要讨论我们的,就是ListBox自己没有能自己把SelectedItem设置正确的情况。本来想当作一个WPF Bug清单的一篇文章的,但是又感觉也许就是有这样变态的需求呢。

    我们用一个非常简单的代码的XAML就可以重现这个问题。

    Demo Window

    运行的效果如下。

    1. TextBox得到焦点

     其实这就是个问题,一个ListBoxItem已经被MouseDown了,可是没有被选中。MouseDown已经被TextBox吃了。结果有可能出现下面的状况。 

    2. 焦点与选中项不一致 

    这个问题在WPF里的其它控件也有,在智者千虑【WPF】如何让TreeView实现右键选中的功能里就描述了TreeView上的相似问题。感觉很恶心。

    一开始使用的是PreviewMouseDown解决,在MouseDown的时候,通过DataContext也好,通过FindAncestor也好,反正是在获得焦点的同时选择上了。

    但是随着项目的进行,这种方法造成DataBindingValidation出现了问题。Validation应该是在LostFocus是对DataContext进行验证;但是使用PreviewMouseDown更改选中项,这个LostFocus就是在别的项被选中之后发现,结果就是用一个无关的数据在新的DataContext上进行验证。

    这个问题又普遍存在于项目各个DataBinding中,分别修改肯定是不行的。只能是不用PreviewMouseDown。用GotFocus,用它的ItemGotFocus来设置选中项。

    为了在现有系统中方便应用,使用了AttachedProperty来实现这个功能。代码如下:

    ListBoxService

    其中FindAncestor是自己定义的一个方法,因为单纯地使用VisualTreeHelper是不足以在所有情况下找到Parent的。代码可参见源代码 

    写好了怎么用呢?我们说了,要以对现有代码最小的变动实现这个功能。可能有人已经想到了,用Style,那个Window的代码根本不用动。只要在App.xaml里加上一个ResourceOK了。代码如下,简单吧。 

    App Resource

    到此,ListBox的行为算是正常些了。正常的运行截图就不发了。

  • 相关阅读:
    WPF 关于拖拽打开文件的注意事项
    asp.net core 3.1中对Mongodb BsonDocument的序列化和反序列化支持
    用百度webuploader分片上传大文件
    多线程学习笔记
    web.config数据库连接字符串加密
    Visual Studio 2010 常用快捷方式
    Team Foundation Server 2013 日常使用使用手册(四)分支与合并
    Team Foundation Server 2013 日常使用使用手册(三)上传新工程、创建任务、创建bug、设置预警
    Team Foundation Server 2013 日常使用使用手册(二)修改、签入、撤销、回滚、对比代码变更
    Team Foundation Server 2013 日常使用使用手册(一)-本地连接TFS、查看任务
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/howtoSetCurrentItemofListBox.html
Copyright © 2020-2023  润新知