我们都知道Window有多种主题(Theme)。一般情况下,显然我们会希望不同 主题下,我们的应用程序的行为不会有变化。或者说,我们不希望为了特定的主 题,为控件写特定的逻辑。然而不幸的是,.NET Framework里一些控件自带的主 题就存在问题,使得我们不得不在使用时,为这个控件在特定的主题下特殊处理 。
下面举一个例子。在 ListBox里放CheckBox,组成一个CheckBoxList应该是 一个比较常见的应用。从理论上来说,在WPF里最简单的方式就是在 ListBox的 ItemTemplate里或是ItemContainerStyle里放一个CheckBox就可以了。
但是实际上,在做这个简单的CheckBoxList的时候,会遇到一个又一个的问 题。首先重申一下文本的意图,怕自己又没有说明白误导大家。
本文不是讨论
CheckBoxList
里的蓝条问题,而是在讨论CheckBox
在不同主题下的不同行为的问题。CheckBoxList
仅仅是个例子。
先来看看效果图。
图1. 两种主题下的CheckBox
在上图中,左侧是Classic主题下的CheckBox。右侧是XP默认的Luna主题下的 CheckBox。
问题1. CheckBox的IsChecked状态与ListBoxItem的IsSelected状态不同步。 如果你想保留选中时的蓝条,那么比较好办,把这两个属性Binding到一起就可 以了。如果你不想要那个选中时的蓝条,会稍稍复杂一些。解决方案很多,就不 赘述了。示例程序中,为减少干扰,不对这个问题进行解决。
问题2. CheckBox所在的Item被选中时,为蓝色。CheckBox里的文字为黑色, 这个与ListBoxItem的默认颜色行为不一致。为了让 CheckBox在被选中时文字为 白色并不难,写个Binding就OK了。这个根本不是问题,但是解决这个问题,造 成了下面的问题,才是主要问题。(当然,如果你隐藏了蓝条,就没有任何问题 。)
问题3. 这个是这篇文章的主要议题,看看下面几个图就知道了。我们对两边 的CheckBoxList做同样的操作。先来右边的。
图2. 选中最后一个CheckBox
图3. 点击刚才选中CheckBox边上的空白,使其选中