【问题标题】:Defining other resources clobbers theme in WPF在 WPF 中定义其他资源破坏主题
【发布时间】:2011-08-03 16:36:19
【问题描述】:

我正在一个 win 表单应用程序中构建一些 WPF 页面。我希望为我的应用程序使用 WPF 主题。没有App.xaml(因为该项目是一个带有 WPF ElementHost 以显示 WPF 表单的 win 表单项目)我在我的表单中添加了我的主题资源字典,如下所示:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Themes/ExpressionDark.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

这适用于此表单上的所有控件以及一些其他 WPF 用户控件,但有些用户控件的主题无法正常工作。我发现受影响的控件定义了自己的资源,如下所示:

    <Grid.Resources>
        <Style TargetType="ComboBox">
            <Setter Property="Margin" Value="0 2 5 2" />
        </Style>
    </Grid.Resources>

资源的位置或资源中的内容似乎并不重要。资源中未键入的任何内容都会阻止该样式所针对的所有内容的主题。我什至试图通过在字典中查找资源来超越它:

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="Template" Value="{DynamicResource ComboBoxTemplate}" />
</Style>

并将我的样式修改为如下所示:

    <Grid.Resources>
        <Style TargetType="ComboBox">
            <Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="Template" Value="{DynamicResource ComboBoxTemplate}" />
            <Setter Property="Margin" Value="0 2 5 2" />
        </Style>
    </Grid.Resources>

但这导致我的组合框完全消失了!

有什么方法可以添加资源来覆盖目标控件而不是摆脱主题?

【问题讨论】:

  • @Dave Clemmer,您为什么要将标签从更具体的 wpf-styles 编辑为不太具体的 styles?在我看来,这是一个非常糟糕的主意!
  • 我重新标记为样式,以便更多人可以找到这篇文章,因为在 wpf 样式下几乎不会出现任何内容。我被告知不鼓励使用 wpf- 标签。在任何情况下,标签描述都应该反映这一点。
  • 有趣。问题在于,当人们选择要关注的标签时,你不能说 wpfstyles 所以你可能会得到 web、android、delphi 等。但我想我无法制定规则。跨度>
  • 您当然可以通过输入[wpf][styles] 来搜索多个标签,但如果能够在 UI 中为您的搜索添加更多标签而无需输入它们,那就太好了。:-)

标签: wpf styles


【解决方案1】:

您只需要将StyleBasedOn 属性设置为旧的隐式Style

<Grid.Resources>
    <Style x:Key="ComboBoxStyle" 
           TargetType="{x:Type ComboBox}" 
           BasedOn="{StaticResource {x:Type ComboBox}}">
        <Setter Property="Margin" Value="0 2 5 2" />
    </Style>

</Grid.Resources>

编辑

因此,如果您不想在所有 ComboBox 上使用资源键,则必须更进一步。我不知道为什么 WPF / WinForms 互操作对隐式样式的处理如此糟糕,但是即使您在此处的资源中添加了隐式样式,并设置了BasedOn="{StaticResource ComboBoxStyle}",您仍然会丢失您的模板。

但是,如果将资源移动到 UserControl,则可以正确执行隐式样式:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Themes/ExpressionDark.xaml" />
        </ResourceDictionary.MergedDictionaries>

        <Style x:Key="ComboBoxStyle" 
               TargetType="{x:Type ComboBox}"
               BasedOn="{StaticResource {x:Type ComboBox}}">
            <Setter Property="Margin" Value="0 2 5 2" />
        </Style>
    </ResourceDictionary>
</UserControl.Resources>

<Grid>
    <Grid.Resources>
        <Style TargetType="{x:Type ComboBox}" 
                   BasedOn="{StaticResource ComboBoxStyle}" />
    </Grid.Resources>

【讨论】:

  • 我不知道你能做到这一点! :)
  • 我没有得到 ComboBoxes 的样式(Margin 属性除外)。我在有和没有资源键的情况下都试过了,两次都得到了相同的结果。此外,我不想在每个组合框上都添加 Style 标签。
  • 我更新了答案以展示如何使用隐式样式。另外,我刚刚在问题中注意到,在有问题的控件上,您没有合并到外部资源中。我确保在更新的答案中显示仍然需要合并的资源。
猜你喜欢
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-18
  • 2011-07-12
相关资源
最近更新 更多