.net net 4.5下的列表/组合框背景和选定颜色

.net net 4.5下的列表/组合框背景和选定颜色,.net,wpf,windows-8,.net,Wpf,Windows 8,我有一个应用程序在windows 7及以下版本上运行得很好,目标是.net 4 framework。 如果该应用程序现在安装在windows 8中(运行.net 4.5,但仍以.net 4为目标),则它会在列表框或组合框中为选定项显示蓝色背景,并为重点项显示白色背景。是否仍要删除此项? 在我的XAML中,我使用以下命令来设置有问题的样式,这似乎解决了Windows8之前的问题 <ListBox.ItemContainerStyle> <Style

我有一个应用程序在windows 7及以下版本上运行得很好,目标是.net 4 framework。
如果该应用程序现在安装在windows 8中(运行.net 4.5,但仍以.net 4为目标),则它会在列表框或组合框中为选定项显示蓝色背景,并为重点项显示白色背景。是否仍要删除此项?
在我的XAML中,我使用以下命令来设置有问题的样式,这似乎解决了Windows8之前的问题

<ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                    <Style.Resources>
                        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
                    </Style.Resources>
                </Style>
            </ListBox.ItemContainerStyle>


它被称为默认主题,它依赖于系统,您并不是真的想搞乱它。您可以通过设置另一个来覆盖它。

您的应用程序覆盖SystemColor.HighlightBrushKey(和其他系统键)的值。这适用于通过参考系统颜色定义其前景色/背景色的控件,就像在Win7默认主题(Aero)中一样。
但是Win8默认主题(Aero2)对颜色的定义不同。所以你的超控无效

主题不需要使用系统颜色。他们碰巧在Win7/Aero中这样做,但只是因为系统颜色被认为是足够的


希望这有帮助。

重新阅读有关框架兼容性的文档,我发现在编译.NET 4并在Windows 8上运行时,实际上不需要它

但我仍然有Windows 7中没有的蓝色背景,我最终找到了一个列表视图,它的样式与我的列表框不同。我发现我实际上不需要为元素选择元素的功能,因此将列表视图更改为itemscontrol为我解决了这个问题

另见:


我忘了告诉你我是如何解决这个问题的。。。。事实证明,您所需要做的就是创建一个空白项容器样式,并将其分配给您的列表框/组合框等。。。。您可以使用它,也可以保留您可能使用的当前样式,例如ListBox样式=“{StaticResource CurrentStyle}”ItemContainerStyle=“{StaticResource BlankListBoxContainerStyle}”/>其中BlankListBoxContainerStyle类似于

<Style x:Key="BlankListBoxContainerStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="FocusVisualStyle"
            Value="{x:Null}"/>
</Style>


以下是我提出的不涉及更改系统颜色或控件模板的方法。只需将列表框包装在新的UserControl中

public partial class StyledListBox : UserControl
{
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public object SelectedItem
    {
        get { return GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }

    public StyledListBox()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(StyledListBox), new FrameworkPropertyMetadata(null));
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(StyledListBox), new FrameworkPropertyMetadata(null));

    public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(StyledListBox), new FrameworkPropertyMetadata(null)
    {
        BindsTwoWayByDefault = true,
        DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    });
}
XAML:


@Oli:Scratch我说的,一个完整的主题从来都不是一个好主意,它可能会激怒一些用户。无论如何,您可以通过设置模板来更改外观,然后控件在每个系统上看起来都是一样的(除非您根据系统进行设置)。我有一个Listbox.ItemsPanel,Listbox.template,Listbox.ItemTemplate和Listbox.itemcontainerstyle已经定义。它工作正常,在我测试过的每个版本的windows上都有相同的视觉样式,但在windows 8上没有。我遗漏了什么?模板通常由模板组件本身组成。也许模板中使用的一个控件现在有了一个不同的模板。我想这是真的,或者至少使用的颜色笔刷已经改变了。我就是不知道是什么,在哪里?请记住.net 4.5更改了所有.net 4程序集,因此任何内容都可能发生更改。请列出这两个版本的所有
SystemColors.*刷子
,并对它们进行比较。谢谢,这很有意义。你知道我如何阻止Aero2在我的应用程序中着色吗?奇怪的是,Aero2控件没有引用系统颜色,而是硬编码了颜色。一种方法是覆盖模板。你有没有找到答案?我没有在windows 8上测试过,所以aero2可能是问题所在,但在windows 7上,我不得不使用InactiveSelectionHighlightBrushKey而不是.NET4.5中的ControlBrushKey。我只是想说Aero2模板中的许多颜色都是硬编码的。悲哀地这包括ComboBoxItem和MenuItem之类的内容。如果您使用Blend或VS编辑复制模板,这将是显而易见的。很好的发现,遗憾的是,该属性仅在.NET4.5中可用,而我的目标是4.0。我会密切关注这篇文章,看看除了强制所有客户机使用4.5之外是否出现了其他解决方案。我修改了这篇文章,因为我最终找到了一个在.NET4中也能完美运行的解决方案。希望它也能帮助您解决问题。请参阅我的答案,以获得不涉及更改ListBox控件模板的解决方案。这会更改datatemplate内边框的颜色,而不是整行的颜色(与ListBox选择不同)…即使设置
,也没有帮助。。。
public partial class StyledListBox : UserControl
{
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public object SelectedItem
    {
        get { return GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }

    public StyledListBox()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(StyledListBox), new FrameworkPropertyMetadata(null));
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(StyledListBox), new FrameworkPropertyMetadata(null));

    public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(StyledListBox), new FrameworkPropertyMetadata(null)
    {
        BindsTwoWayByDefault = true,
        DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    });
}
<UserControl x:Class="StyledListBox"

     <ListBox ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}"
              SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type common:StyledListBox}}}">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border>
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                                             Value="True">
                                    <Setter Property="Background" Value="Red" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>

                    <ContentPresenter ContentTemplate="{Binding ItemTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StyledListBox}}}" />
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</UserControl>