【问题标题】:How can I access the default styles for a theme?如何访问主题的默认样式?
【发布时间】:2012-08-21 02:58:32
【问题描述】:

在我们的 WPF 应用程序中,我们有一个自定义列表框,当它没有样式时,它与默认的 Windows 主题相匹配,例如突出显示、悬停或选定的项目(即漂亮的蓝色半透明渐变。)

但是,当我们尝试创建自己的 ListBoxItem 模板并使用此代码中的值时...

<Trigger Property="Selector.IsSelected" Value="True">
    <Setter TargetName="Bd" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
    <Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>

...控件失去了 Aero 主题的所有痕迹,恢复为旧的 Win95/Classic 外观。我们怎么说'嘿...将主题的'突出显示'样式应用到我们的边框。'?

同样,资源显然是加载的,直到我们重新模板化控件,但我们应该如何访问主题的内置样式?毕竟,那种“选择”的外观无处不在……ListBox、ComboBox、ListView,无处不在。我们只是希望它也在我们的控制之下,而不必重新发明轮子。

注意:我们使用 ShowMeTheTemplate.exe 应用程序来获取默认的“Aero”样式,但同样,这不是我们在运行它时看到的。

【问题讨论】:

    标签: wpf controltemplate theming


    【解决方案1】:

    您可以在Style 中使用BasedOn="{StaticResource {x:Type ItemType}}" 来修改现有模板,但是无法将默认模板的一部分与您的自定义模板合并,模板是单一的。

    【讨论】:

    • 如果我不想合并它们,而只想访问内部怎么办?例如,WPF 主题中的每个可选内容基本上都具有相同的“IsSelected”外观,无论是 ListBox、ComboBox、TreeView 等。(好吧,所以文本框的选择是不同的,但我离题了。)它们都有一个共同的外观模板中名为“Bd”的边框。这是否意味着虽然它们全部相同,但它们也是同一事物的独立副本,因此,我必须创建自己的完全独立副本?
    • 是的,它们是独立的。此外,您应该将模板视为黑盒,默认模板取决于操作系统,因此您无法知道运行时模板中的实际内容。这就是为什么你不应该访问模板内的控件,即使理论上你可以。
    • 我唯一的问题是 WPF 确实定义了选择高亮画笔、高亮前景色等,但它们自己的默认样式似乎没有使用它们。这是一个耻辱。对于诸如此类的常见事物,他们应该公开主题所呈现的事物。这将有助于提供更一致的视觉用户体验。如果这些价值观并不能真正反映真正的全球价值,那么在全球范围内定义这些价值观又有什么意义呢?比其他任何东西都更修辞所以没有必要回复,但我认为MS在判断时犯了一个错误,隐藏了这一切。
    • 一些默认样式通过引用系统颜色键(e.)来使用这些样式,但可能用法不一致......
    • 是的,我知道了密钥的用法。这就是我要说的……至少让我们设置与这些全局键无关的动态资源,但他们甚至不这样做。令人沮丧,因为这意味着我们必须准确地重新创建已经创建的东西,因为它没有被暴露......我们必须每个主题都这样做一次。我想另一种方法是完全忽略主题,只使用自己独特的外观,就像 Photoshop,甚至是现在最新的 VS 一样。
    【解决方案2】:

    您的答案似乎在这里:

    ....您应该使用ItemsContainerStyle 而不是仅仅定义一个替换ItemTemplate...并使用BasedOn 定义您的Style 以继承主题为您的FrameworkElement 元素定义的默认样式。

    您还可以使用其他一些技术来利用主题定义的默认样式(...只是为您提供了额外的选项)。

    还有一种上面没有提到的技术,它使用标记扩展来合并一些样式(即你可以合并默认样式和你的样式)。

    【讨论】:

    • 我在这里看到的问题是,所有这些都以一种或另一种方式基于ListBoxItem 的整体风格,但这不是我所追求的。在ListBoxItem 的模板内有一个边框,当使用 Aero 并且该项目被选中时,该边框具有蓝色渐变背景。 是我所追求的...应用于边框的背景,而不是ListBoxItem 的整体模板。您也不能简单地替换模板,因为设置背景样式的触发器也是模板的一部分。希望这是有道理的。
    • 在 ShowMeTheTemplate 中再次查看 ListBoxItem 模板...。您错过了 Selector.IsSelected 上的 MultiDataTrigger 等,它修改了边框“Bd”...。
    • 我实际上非常熟悉该工具,并将其代码库作为我们解决方案的一部分,位于“Utilities”文件夹下,正好用于类似这样的事情,但这仍然没有不要解释我在追求什么。我正在寻找模板 within 的边框样式。您无法替换模板的子部分,因此我必须复制整个内容,更不用说为每个主题创建一个。我只想要主题已经提供的边框和背景。希望这更有意义。
    • 也许这会对你有所帮助...stackoverflow.com/questions/5736989/…
    • 再说一次,我非常精通这些,这不是我要问的。我这么说是因为这仍然不能解释为什么我不能将相同的 KEY 用于背景画笔,因为您可以动态更改该键的内容。换句话说,在他们的示例中,'{DynamicResource {x:Static SystemColors.HighlightBrushKey}}' 行应该指代高光画笔,无论它是基于实体、渐变还是其他,无论主题如何。但事实并非如此。它似乎总是指向实心画笔。如果我想要渐变版本,我必须为每个主题明确定义它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2014-02-15
    • 2011-04-01
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    相关资源
    最近更新 更多