tags:

views:

34

answers:

2

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 xp style set to me. i.e. he has 'Windows Classic style'.

My question is, 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>
+1  A: 

Using third party UI controls will help you to keep consistancy.

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 XP, Vista and Windows 7.

Pierre 303
Yes I agree, makes it more familiar i guess if same as OS. however, the user has asked for the button to be green when checked and I don't want to have to ask them to change their os settings.
HAdes
Then go for a third party button control that has its own rendering logic. Also you may try to see if by setting explicit colors on the button, you may be able to bypass system appearance settings.
Pierre 303
yeah I have already tried that and it does keep the color, however my trigger then doesn't work. 3rd party controls are not an option.
HAdes
Jay's answer may save your day !
Pierre 303
+2  A: 

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"

Jay
Having a bit of trouble getting this Jay. I don't appear to have PresentationFramework.Aero. Could you please provide an example with the Microsoft_Windows_Themes:ButtonChrome stripped out as I am getting errors left right and center. cheers.
HAdes
@HAdes I updated with a simplified version. Pull out the Chrome and try it.
Jay
When you say 'pull out the chrome' I'm not sure what you mean. If you mean remove the line 'Microsoft_Windows_Themes:ButtonChrome...', then i did and now it's nothing more than a transparent box. BTW i don't have expr blend yet, so doing everything by hand.
HAdes
@HAdes That is right -- without the chrome, the template is empty -- all it can do is display what is in the `ContentPresenter`. Try wrapping the `ContentPresenter` inside a `Border` with the `Background` property set, as a start toward re-creating the button. You can also find ready-made control themes online for free, such as http://wpf.codeplex.com/wikipage?title=WPF%20Themes. You can use them or look at the source code to see how they're put together.
Jay