0
votes

i want to define the style of some buttons of my WPF application at the Window level. Here is the code:

<Style x:Key="MainButtonStyle" TargetType="Button">
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="60"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Background" Value="White"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="ButtonGrid">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">

                                <VisualStateGroup.Transitions>
                                    <!--Take one half second to transition to the MouseOver state.-->
                                    <VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" />
                                </VisualStateGroup.Transitions>

                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background" To="Cyan"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background" To="Red"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

What i want to do is to define some style properties of the button like Width or Color and also set a VisualState to stablish the behaviour of the button on Pressed, MouseOver, etc.

But that code does not work, because once the "Template" property is defined, all other properties (Width, Margin, etc) are forgotten, what is the proper way to make it work? Should i define all the button properties inside the "Grid" Properties of the Template?

Thank you.

EDIT: A SOLUTION. BUT I DON'T UNDERSTAND WHY

Ok, i have a solution, now it is working fine but i still don't understand why does WPF behaves this way. I'm new in this language and it is realy hard to know what property to work with in different Controls and how to implement it... I'm finding it zero intuitive in many cases... I hope it is just that i'm a newbie.

Any case, the problem was twice:

First: All the properties set by the "MainButtonStyle" works fine except the "Background", which seems to be overriden by the Grid at the ControlTemplate, so i had to set the BackGround property at the Grid in place of setting it at the Button... I don't finish to understand why is it happening.

Second: The "StoryBoard.TargetProperty="Background" can't be assigned to a Color object, i had to specify "StoryBoard.TargetProperty="BackGround.Color" to properly assign a Color object. And like before, i don't understand why. If in other Controls i can set the BackGround property directly to a Color value like "BackGround = "Red", why in a StoryBoard i have to set it "BackGround.Color="Red"?

Ok, now the code working:

<Style x:Key="MainButtonStyle" TargetType="Button">
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="60"/>
        <Setter Property="Margin" Value="5"/>            
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Background="White" x:Name="ButtonGrid">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>                                            
                                        <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background.Color" To="Cyan"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background.Color" To="DarkSalmon"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

So, there is the solution, but if someone could explain better WHY, i would appreciate it.

1
Where is your template ? Storyboard.TargetName="borderColor" ? border is missing.Shivam cv
Your displayed ControlTemplate has nothing in it except from your VisualStateGroups and they won't do anything because there are no UI elements for them to change. The answer regarding the properties is to map them to properties of UI elements in your ControlTemplate... if only you had some. See http://wpftutorial.net/templates.html for an example of what I mean.Sheridan
Sorry but i don´t see it.... I have a global Style with TarrgetType Button and inside of it a ControlTemplate also targeting the Button. I supposed that it should apply to all buttons in my UI with Style = "{StaticResource MainButtonStyle}"... I can´t see why it is not happening...MorgoZ

1 Answers

0
votes

When you are defining a style for a control and you are also overriding the default control template the button no longer has its default layout. It only contains those elements you define in the control template. IN THE ABOVE CASE THE BUTTON ONLY CONTAINS ONE GRID.