I'm really surprised that this question does not appear to have been asked yet... if it has, but I just couldn't find it, apologies.
Ok, so my work computer has just been upgraded from Windows 7 to Windows 8. To my absolute horror, my WPF Application looks different in several ways... by different, I mean worse, uglier, controls not lined up correctly, etc. Here is an example:
Windows 7:
Windows 8:
Windows 8 problems (just from this image):
So, my question is this:
Why do WPF Applications look different between Windows 7 and Windows 8 and can this be fixed?
To clarify this, I'm not after a list of differences between WPF on the two operating systems. I'm also not after fixes for the individual points listed above. I would like for someone to explain why these UIs look different, eg. what is causing these differences. I have also heard talk of some system settings in WPF that would enable me to make the PC render the application as if it were on Windows 7, but I don't know how truthful that was.
UPDATE >>>
As @AndrasSebö kindly pointed out, there is a StackOverflow question named Windows 7 theme for WPF?, which fixes a similar problem for Windows XP. Unfortunately, it doesn't seem to have any effect on Windows 8. Are there any Microsoft users out there that actually know what differences were implemented to cause this problem? Or anyone?
UPDATE 2 >>>
Ok, so after some more testing, I'm beginning to think that this problem is not related to the Windows Theme. Using the code provided in @Gusdor's answer, I tried changing the theme to Aero
and there was no visible difference... that got me thinking. I then changed it to Luna
to test that code and it worked.
By 'worked', I mean that the Windows Theme changed, but the UI controls, or more accurately, the incorrect Padding
and Margin
remained. I then tried changing the Theme to Luna
using the XAML method mentioned by @AndrasSebö and the same thing happened... the ScrollBar
s looked different, so I could see that the Theme had changed, but the problem remained.
So now I'm thinking that this might have something to do with the fact that this is a brand new computer that I'm working on... might there be some dll or setting that I need to install? I'm really just guessing here - I have the whole Microsoft .NET Framework installed to version 4.5.1 as I'm on Windows 8.1.
This is an absolute nightmare as I don't have time to go and fix every view in this large application. Please help if you can.
NET Core does run on Windows 7 (currently SP1 is required). You can see the progress of WPF on .
Universal Windows Platform. Both Windows Forms and WPF are old, and Microsoft is pointing developers towards its Universal Windows Platform (UWP) instead. UWP is an evolution of the new application platform introduced in Windows 8 in 2012.
Window is the root control that must be used to hold/host other controls (e.g. Button) as container. Page is a control which can be hosted in other container controls like NavigationWindow or Frame. Page control has its own goal to serve like other controls (e.g. Button). Page is to create browser like applications.
Ok, so unfortunately, there was no quick fix for this problem. If you are in a similar situation and the answers supplied here do not work for you either, then here is a summary of the changes that I manually needed to make in order to make the UI on Windows 8 appear the same as the UI on Windows 7.
TextBox
: Needed to add Padding
to default Style
:
<Setter Property="Padding" Value="1.5,2" />
ListBoxItem
: Needed to provide new ControlTemplate
to hide selection and mouse over background colours:
<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
: Needed to provide new ControlTemplate
to change selection and mouse over background colours:
<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
: Needed to provide new ControlTemplate
to stop tick from appearing back to front when Bullet
is to the right of the Content
(thanks to Fredrik's answer to the Default ControlTemplate for CheckBox question here on 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>
To remove the horrendous title bar and display the default Windows 8 one: Needed to upgrade to .NET 4.5 and utilise the included System.Windows.Controls.Ribbon
namespace library instead of the separate 'Microsoft Ribbon for WPF' (RibbonControlsLibrary) dll previously used.
Unfortunately, I never found out how to reproduce the SemiBold
setting of the FontWeight
property on Windows 8. If anyone knows how to do this, please let me know.
On the whole, the move to Windows 8 has been a painful and troubling experience. I hope this information will help others in a slightly less painful manner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With