为什么WPF应用程序在Windows 7和Windows 8之间看起来有所不同,这可以修复吗?

She*_*dan 20 windows wpf render difference

我真的很惊讶这个问题似乎还没有被问到......如果有的话,但是我找不到它,道歉.

好的,所以我的工作计算机刚刚从Windows 7升级到Windows 8.令我非常恐怖的是,我的WPF应用程序在几个方面看起来有所不同......不同,我的意思是更糟糕的是,丑陋,控件没有正确排列等等.这是一个例子:

Windows 7的:

在此输入图像描述

Windows 8:

在此输入图像描述

Windows 8问题(仅从此图像):

  • 错误的标题栏包括按钮(最小化,关闭等)
  • 标题栏中的字体大小错误
  • 标题中的FontWeight错误(Windows 7 SemiBold设置= Windows 8粗体设置)
  • 标题栏中的图标(或文本)未对齐
  • 标题栏中的图标非常模糊
  • 错误的填充和/或边距设置将左侧的项目隔开
  • 错误的填充和/或边距设置会缩小右侧的文本框高度
  • 左侧项目的"隐藏"默认选择颜色不再隐藏
  • 回到正面复选框勾选
  • 某些按钮上的图像非常模糊

所以,我的问题是:

为什么WPF应用程序在Windows 7和Windows 8之间看起来有所不同,这可以修复吗?

为了澄清这一点,我不是在两个操作系统上的WPF之间的差异列表之后.我也没有修复上面列出的各个点.我想让某人解释为什么这些UI看起来不同,例如.是什么导致了这些差异.我也听说过WPF中的一些系统设置,这使我能够让PC渲染应用程序就像在Windows 7上一样,但我不知道它是多么真实.


更新>>>

正如@AndrasSebö亲切地指出的那样,WPF有一个名为Windows 7主题的StackOverflow问题,它修复了Windows XP的类似问题.不幸的是,它似乎对Windows 8没有任何影响.是否有任何微软用户确实知道实施了哪些差异导致此问题?还是有人?


更新2 >>>

好了,经过一番更多的测试,我开始认为这个问题是相关的Windows主题.使用@ Gusdor答案中提供的代码,我尝试将主题更改为,Aero并没有明显的区别......这让我思考.然后我将其更改Luna为测试该代码并且它有效.

通过'工作',我的意思是Windows主题改变了,但UI控制,或更准确地说,不正确PaddingMargin保持.然后我尝试将主题更改为Luna使用@AndrasSebö提到的XAML方法,同样的事情发生了... ScrollBars看起来不同,所以我可以看到主题已经改变,但问题仍然存在.

所以现在我认为这可能与我正在研究的这是一台全新的计算机这个事实有关...可能有一些我需要安装的dll或设置?我真的只是在这里猜测 - 我将整个Microsoft .NET Framework安装到版本4.5.1,因为我在Windows 8.1上.

这是一个绝对的噩梦,因为我没有时间去修复这个大型应用程序中的每个视图.如果可以的话请帮忙.

She*_*dan 10

好吧,不幸的是,没有快速解决这个问题.如果您处于类似情况并且此处提供的答案也不适合您,那么这里是我手动需要进行的更改的摘要,以使Windows 8上的UI看起来与Windows上的UI相同7.

TextBox:需要添加Padding到默认值Style:

<Setter Property="Padding" Value="1.5,2" />
Run Code Online (Sandbox Code Playgroud)

ListBoxItem:需要提供新ControlTemplate的隐藏选择和鼠标悬停在背景颜色:

<Style x:Key="DefaultListBoxItem" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Padding" Value="0" />
    <Setter Property="Margin" Value="2,0,1,0" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver" />
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected" /> 
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/>
                    <Rectangle x:Name="FocusVisualElement" Fill="{x:Null}" Stroke="{x:Null}" StrokeThickness="0" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

ComboBoxItem:需要提供新ControlTemplate的更改选择和鼠标在背景颜色:

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true" Background="Transparent">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF47484C" /> <!-- Background mouse over colour -->
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="White" /> <!-- Foreground mouse over colour -->
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF47484C" /> <!-- Background selection colour -->
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="White" /> <!-- Foreground selection colour -->
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="Red" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

CheckBox:需要提供新ControlTemplate的停止勾选Bullet在右侧出现时返回到前面Content(感谢Fredrik 对Stack Overflow上的CheckBox问题的默认ControlTemplate的回答:

<SolidColorBrush x:Key="CheckBoxFillNormal" Color="#F4F4F4" />
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F" />
<Style x:Key="EmptyCheckBoxFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="1" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="CheckRadioFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
    <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator Background="Transparent" SnapsToDevicePixels="true">
                    <BulletDecorator.Bullet>
                        <Aero:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
                    </BulletDecorator.Bullet>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasContent" Value="true">
                        <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
                        <Setter Property="Padding" Value="4,0,0,0"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

删除可怕的标题栏并显示默认的Windows 8:需要升级到.NET 4.5并使用包含的System.Windows.Controls.Ribbon命名空间库而不是以前使用的单独的"Microsoft Ribbon for WPF"(RibbonControlsLibrary)dll.

不幸的是,我从未发现如何在Windows 8上重现该属性的SemiBold设置FontWeight.如果有人知道如何执行此操作,请告诉我.

总的来说,转向Windows 8一直是一个痛苦和令人不安的经历.我希望这些信息会以稍微不那么痛苦的方式帮助其他人.