Different Windows XP styles are changing my control apperances, how do I avoid it?
I thought everything was looking good with my user controls, styles and layout, etc., until I released a version for the user to test. They asked if the toggle button could be green when checked. I 开发者_如何学运维said it is, but it wasn't. I checked on my machine and it was green. Turns out he has a different Windows XP style set than me. That is, he has 'Windows Classic style'.
How do I avoid this and enforce my styles regardless of the Windows style?
<UserControl.Resources>
<Style x:Key="MyToggStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="On" />
<Setter Property="IsChecked" Value="True" />
<Setter Property="Background" Value="Green" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="Pff" />
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<ToggleButton FontWeight="Bold"
IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"
Style="{StaticResource MyToggStyle}"/>
</Grid>
You have to completely override the control template, because the default chrome utilizes the OS settings.
This is much easier to do in Expression Blend than in Visual Studio.
Here is a simplified version of the default template for a ToggleButton
:
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Notice that the control utilizes Microsoft_Windows_Themes:ButtonChrome
. If you get rid of or replace that chrome, your users display should match your own (don't remove the ContentPresenter
, though -- that is where the button text/content goes). If you just remove it, you'll have a flat button. You can create visual states and animations for it, but again that is much easier in Blend.
Note: the namespace aliased by Microsoft_Windows_Themes
in this case is
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Using third party UI controls will help you to keep consistency.
I did it using DevExpress controls. They have a skinning feature that is quite nice.
I personnaly dislike applications that doesn't respect the OS's appearance settings.
Don't forget that using standard .NET UI controls will allow you to take advantage of the new OS features. As an illustration, try an application with the standard ProgressBar control on Windows XP, Windows Vista and Windows 7.
精彩评论