zoukankan      html  css  js  c++  java
  • [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的行为算是正常些了。正常的运行截图就不发了。

  • 相关阅读:
    JS打印代码示例
    javascript图片360°旋转
    动态载入/删除/更新外部 JavaScript/Css 文件
    AviSynth入门与应用指南
    汇编64讲(搞免杀、破解必看)在线观看
    C#模拟登录总结
    同时使用apache和IIS,共用80端口的一个解决方案
    Dos命令集合
    批处理for命令详解
    JavaScript定义类的几种方式
  • 原文地址:https://www.cnblogs.com/nankezhishi/p/howtoSetCurrentItemofListBox.html
Copyright © 2011-2022 走看看