组合框背景不是在窗口8被施加(Combobox background not being appli

2019-09-01 00:28发布

我使用WPF主题有点困惑。 我想有WPF的屏幕看起来在Vista,Windows 7和Windows 8一样的,所以我也相应风格的组件和它们不构成除非问题时,在Windows 8上运行。例如我有一个组合框,我改变这样的XAML它的默认背景。

<Style TargetType="{x:Type ComboBox}" >
    <Setter Property="FontStyle" Value="Normal"/>
    <Setter Property="Height" Value="24" />
    <Setter Property="Background" Value="{StaticResource GradientButtonBackgroundBrush}"/>
</Style>

该组合框背景属性已在Windows 8没有影响,我得到的是与右边的箭头为扁平长方形(默认的Windows 8组合框,这是相当设计不当!)。

所以,我的问题是,如何获取组合框看起来一样在所有版本的Windows。 我尝试添加的Windows Aero主题,在我的App.xaml像下面,但它具有组合框显示没有影响。 这是我如何加入Aero主题

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/PresentationFramework.Aero;component/themes/aero.normalcolor.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

还有关于主题的另一个疑问。 我建立一个Windows 7的机器,它在默认情况下(我相信)在WPF应用程序具有Aero主题集。 因此,Windows 7计算机上查看时,我的所有样式都基于Aero主题。 如果我运行XP说应用会发生什么。 然后我需要在代码中列出上面添加在App.xaml中的资源字典(Aero主题)的入口?

我知道我的问题是有点模糊,但相信我,我真的对不同的Windows版本WPF的默认主题混淆。

编辑:我仍然不能根据我的需求得到组合框的风格。 组合框仍然看起来像一个灰色的矩形。

下面是我做的。 我从微软的网站下载的Aero.NormalColor.xaml并列入申请的主题文件夹中。 然后,我添加在App.xaml中以下

    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Themes/Aero.NormalColor.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

然后我编译应用程序和以前显示部署在Windows 8的仍然是相同的组合框。 请注意,所有其他元素,会根据主题风格正确。 我也做了同样用Luna.Metallic.xaml环节都被称呼除了组合框

我相信,当我打开一个特定的主题,这与控件模板定义样式,那么就应该通过WPF采摘。 我很困惑,为什么只有组合框 ,甚至给它之后的Aero(或月神)控制模板不改变它的外观。 有任何想法吗 ?

在Windows 8的组合框的外观EDIT 2截屏

Answer 1:

那么该ComboBox可点击区域实际上是一个ToggleButton

如果你看一下StyleToggleButton在Windows 8,你看到的是这样的:

<ControlTemplate TargetType="{x:Type ToggleButton}">
  <Border x:Name="templateRoot"
          Background="{StaticResource ComboBox.Static.Background}"
          BorderBrush="{StaticResource ComboBox.Static.Border}"
          BorderThickness="{TemplateBinding BorderThickness}"
          SnapsToDevicePixels="true">
...

正如你可以看到从上面, Background使用不是{TemplateBinding Background} ,但{StaticResource ComboBox.Static.Background} 因此,为什么你看到没有效果,当你设置的Background该属性在Windows 8 ComboBox

如果您寻找携带Style在不同的操作系统版本(而不必走回头路,继续检查是否有新版本搞砸了你的过度的游乐设施),简单的规则就是创建它自己。

创建Style并将其设置为通过应用TargetType和不带Key即可自动应用。 在任何操作系统这样,这是你的Style是被使用,而不是默认的根本之一。

如你期望在每一个OS这从而保证你的代码运行的。 基于任何操作系统的默认的你的风格和它调整到你的心脏的内容。

侧面说明

从可用性的POV给用户一个Windows 7 ComboBox在在Windows 8上运行的应用程序是不是很漂亮的(除非你的整个应用程序看起来像一个Windows 7应用程序,它是更糟糕)。 你希望用户来适应你的应用程序的风格的,忘记了他用来从所有其他应用他在他的操作系统,使用基于OS的默认样式使用。 如果你有特别的理由这样做,继续但考虑影响。

只是举例说明你在Windows 8风格的东西你不是球迷,以及我是相反的。 其实我不喜欢在Windows 8干净,简约的外观。 心无杂念的UserExperience与闪烁的渐变和东西抛出你把你在他们面前放的内容。 这是一个永远继续的争论。 ABT什么终端用户期望并认为不仅仅是你的想法是好的,而写程序一定要小心。

更新:

对相关答案,请首先发表评论。 您的答案,您的评论的更新没有关系。

确定和你的问题的编辑,你尝试过在Windows 8,因为没有工作是什么PresentationFramework.Aero.dll无法在Windows 8这正是持有存在Aero.NormalColor.xaml 。 在Windows 8你的选择是PresentationFramework.Aero2.dll这是默认的, PresentationFramework.AeroLite.dll我认为这是使用Windows Server 2012中(不知道)

尝试编译在Windows 8程序,你会看到,它甚至不希望编译。

你必须明确地添加到参考PresentationFramework.AeroPresentationUI (我认为这是.net3的一部分)到项目中。

然后,你必须编辑您的Aero.NormalColor.xaml喜欢的东西:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
                    xmlns:ui="clr-namespace:System.Windows.Documents;assembly=PresentationUI">
...

^^我们明确指出了Aero主题大会。 我不使用Windows的7所以我不知道这是一个的所需的全部。 但你可以给一个尝试。

尝试编译在Windows 8的代码,以确保它会正常工作在Windows 8



Answer 2:

最后,无奈小时后,我来到翻过的解释后这里 。 对于滚动答案 。 这正好说明我一直面临着特别的Aero风格没有得到应用到我的组合框的场景。 链接解释得很好,为什么我们需要一个支持算法FMP属性添加到每一个我们的风格,如果我们不想默认的操作系统风格被拾起元素。 因此,增加这个支持算法FMP对于ComboBox得到它为我工作。

<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">

现在Aero主题样式用于组合框。 作为@Viv指出,它可能还需要PresentationFramework.Aero.dll和PresentationUI.dll复制到Windows 8设备,因为它们没有与操作系统提供。

谢谢,NIRVAN



Answer 3:

我做了一些关于内置模板黑客攻击的。 不干净的解决方案,但去除了推出自己的模板的头痛。 背后基本代码绑定内置模板边界的属性与组合框的属性。

<Style TargetType="ComboBox">
    <Setter Property="Border.Background" Value="White"/>
    <EventSetter Event="Loaded" Handler="ComboBox_Loaded"/>
    <Style.Triggers>
        <Trigger Property="IsReadOnly" Value="True">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Background" Value="{StaticResource ResourceKey=FocusedControlBackcolorBrush}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/>
        </Trigger>
    </Style.Triggers>
</Style>


    private void ComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        var comboBox = sender as ComboBox;
        var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton;
        var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border;
        if (border != null)
        {
            Binding b = new Binding("Background");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1);
            BindingOperations.SetBinding(border, Control.BackgroundProperty, b);

            b = new Binding("BorderBrush");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1);
            BindingOperations.SetBinding(border, Control.BorderBrushProperty, b);
        }
    }


Answer 4:

在应对@Viv

@Viv,我觉得你的答案是非常明确的,但不知何故,你的意见/建议不可消化给我,我将简要地提及为什么

您的意见

如果您寻找携带在不同的操作系统版本样式(而不必走回头路,继续检查是否有新版本搞砸了你的过度的游乐设施),简单的规则就是创建它自己。

这似乎行不通。 主题的想法是一致的外观中的应用及翻过所有平台的所有元素的创建。 所以,如果我使用了框架提供,无论什么特定的主题,我应该能够实现的一致性令人满意的程度,至少在当前的主要平台。 首先,不是每个人都有专长从头开始创建所有的风格和模板。 主题的概念应该是,

“框架提供商提供,这将正常情况下,如果有人希望推出自己的主题,欢迎他这样做很好的工作主题”。

相反,这里的概念似乎像

“框架提供商提供的主题,它不guranted,这将是一致的,并没有打破的工作,所以一直推出的主题”

您的报价

正如你可以从上面看到,使用背景不是{TemplateBinding背景} {不过的StaticResource ComboBox.Static.Background}。 因此,为什么你看不到效果时,你该组合框设置背景属性在Windows 8

我不知道是谁的想法是做一个模板的方式! 一定是他的头脑还是我太愚蠢理解的优势。 试想一下,我用我的应用程序和明天一些蓝色的主题,在Windows 9,有人定义了红色作为{StaticResource的ComboBox.Static.Background}。 所以,你猜怎么着,我有一个奇特的窗口画面现在我的所有元素为主题的“蓝”,只有组合框的出现“红色”。 我的意思是主题的想法在这里打破!

您的边注

只是举例说明你在Windows 8风格的东西你不是球迷,以及我是相反的。 其实我不喜欢在Windows 8干净,简约的外观。

我的组合框看起来像一个残疾人按钮,我甚至不能改变它的背景! 按钮并不像他们点击! 任何方式你说,这是个人的选择着,当然。

我的结论我会等待一段时间,如果有一个人对我如何获得组合框上Windows 8的工作你的回答提出的真相任何建议,所以我会很乐意将其标记为正确的,如果我没有得到任何替代解。

NIRVAN



Answer 5:

较新的模板有一个硬编码的背景颜色不尊重任何背景样式网格状> ToggleButton->边境。 基于从@Matstar答案我做了一个方式同步跨越的背景色。

您仍然可以设置绑定到背景颜色和代码会挑选这件事并在需要时重新应用此:

<ComboBox ItemsSource="{Binding Values}" x:Name="Cbo2"
Background="{Binding Path=SelectedValueBgColor}" ... />

然后在xaml.cs

cbo.Loaded += (sender, args) =>
{
    var comboBox = sender as ComboBox;
    if (comboBox != null)
    {
        var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton;
        var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border;
        if (border != null)
        {
            var existing = BindingOperations.GetBinding(comboBox, BackgroundProperty);
            BindingOperations.SetBinding(border, BackgroundProperty, existing);
        }
    }
};

确保你的背景结合从不返回null

如果您有任何有意义的值返回透明或白色或其他一些默认。 如果绑定到返回null组合框将停止工作的背景。

请务必通知物业在你的背景改为绑定是否需要刷新时事件发生。



文章来源: Combobox background not being applied in windows 8