我真的很惊讶,这个问题似乎还没有被问到…如果有,但我无法find它,道歉。
好吧,我的工作电脑刚刚从Windows 7升级到Windows 8.令人绝对惊讶的是,我的WPF应用程序在几个方面看起来不同… …不同,我的意思是更糟,更糟的是,控制不正确排列等等。这里是一个例子:
Windows 7的:
Windows 8:
Windows 8的问题(只是从这个图像):
所以,我的问题是这样的:
为什么WPF应用程序在Windows 7和Windows 8之间看起来不同,可以解决这个问题吗?
为了澄清这一点,我没有在两个操作系统上的WPF之间的差异列表。 我也没有修复上面列出的个人点。 我想有人解释为什么这些用户界面看起来不同,例如。 什么是造成这些差异。 我也听说过WPF中的一些系统设置,使我能够使PC 像在Windows 7上一样呈现应用程序,但是我不知道这是多么真实。
更新>>>
作为@AndrasSebö好心指出,有一个名为Windows 7的WPF主题的StackOverflow问题? ,它修复了Windows XP的类似问题。 不幸的是,它似乎没有对Windows 8有任何影响。有没有在那里的任何微软用户, 实际上知道什么差异被实施导致这个问题? 或者任何人?
更新2 >>>
好的,经过一些testing之后,我开始认为这个问题与Windows主题无关。 使用@Gusdor的答案中提供的代码,我尝试将主题改为Aero
,没有明显的区别…这让我想到了。 然后我把它改成了Luna
来testing这个代码,它工作。
通过'工作',我的意思是Windows主题改变,但用户界面控制,或更准确地说,不正确的Padding
和Margin
仍然存在。 然后,我试着用@AndrasSebö提到的XAML方法来改变主题到Luna
,同样的事情发生了… ScrollBar
条看起来不一样,所以我可以看到主题已经改变,但问题依然存在。
所以现在我想这可能与这是一个全新的计算机,我正在工作的事实…可能有一些DLL或设置,我需要安装? 我真的只是猜测在这里 – 我已经安装到4.5.1版本的整个Microsoft .NET Framework,因为我在Windows 8.1上。
这是一个绝对的噩梦,因为我没有时间去解决这个大型应用程序中的所有视图。 如果可以的话请帮忙。
好吧,不幸的是,这个问题没有解决。 如果您遇到类似的情况,并且这里提供的答案也不适用于您,那么下面是为了使Windows 8上的UI看起来与Windows上的UI相同而手动进行的更改的摘要7。
TextBox
:需要添加Padding
默认Style
:
<Setter Property="Padding" Value="1.5,2" />
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>
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>
CheckBox
:需要提供新的ControlTemplate
,以便在Bullet
位于Content
右侧时停止打勾(感谢Fredrik 对于CheckBox问题的默认ControlTemplate的回答,这里是关于Stack Overflow的问题:
<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>
要删除可怕的标题栏,并显示默认的Windows 8之一:需要升级到.NET 4.5,并利用所包含的System.Windows.Controls.Ribbon
命名空间库,而不是单独的“微软功能区的WPF”(RibbonControlsLibrary)dll以前使用。
不幸的是,我从来没有发现如何重现Windows 8的FontWeight
属性的SemiBold
设置。如果有人知道如何做到这一点,请让我知道。
总的来说,迁移到Windows 8是一个痛苦和令人不安的经验。 我希望这些信息能够以一种稍微不痛的方式帮助别人。
如果您使用WPF没有自定义(显式)风格,它将使用标准的Windows 7航空风格。 在Windows 8的情况下是不同的(aero2)。
如果你想确定,你的应用程序在windows7和windows8上看起来是一样的,我建议你自己定义边距,填充,字体等等。
该问题(如其他答案中所述)是WPF选择由操作系统版本确定的默认主题。
你需要重写这个行为。 这篇文章描述了如何:
WPF带有几个主题程序集,每个Windows主题(Luna,Royale和Aero以及后备主题,Classic)都有一个主题程序集。通常根据您当前的系统主题加载主题,但是如果要为您创建一致的外观应用程序,你可能想强制加载一个特定的。
要做到这一点,只需将下面的代码添加到应用程序启动事件中(此示例显示如何使用Aero主题):
Uri uri = new Uri(“PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\\themes/aero.normalcolor.xaml”, UriKind.Relative); Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);
指定版本和公钥标记非常重要。 否则,您将不得不将主题程序集复制到可执行文件的文件夹中。 我将它添加到合并字典集合的原因是我不想失去添加到App.xaml文件中的其他资源。
你的问题可能与此有关
目前WPF功能区库中存在一个错误,如果正在使用RibbonWindow,则导致Windows 8主题不适用。
此外,Windows 7和8对其控件(如文本框)使用简单的不同样式。 在为多平台开发时,无论是Windows还是Windows,都必须注意尺寸,边距和填充的改变。 而不是绝对值,你应该让控件通过避免设置明确的高度或宽度来决定对空间的需求。