5

I'm trying to change the font color of a button when the button is clicked. I have tried many different things but none have worked. This is the latest thing I tried and what I believe should be the answer but its not working. Can someone help? PointerOver isworking fine, but Focused is not doing anything when the button is clicked.

<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="FontWeight" Value="Normal" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid
                    x:Name="RootGrid"
                    Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>

                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="ContentPresenter.FontWeight" Value="Bold" />
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Pressed"/>

                            <VisualState x:Name="Focused">
                                <VisualState.Setters>
                                    <Setter Target="ContentPresenter.Foreground" Value="Purple" />
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Disabled">
                            </VisualState>
                        </VisualStateGroup>

                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter
                        x:Name="ContentPresenter"
                        Content="{TemplateBinding Content}"
                        ContentTransitions="{TemplateBinding ContentTransitions}"
                        ContentTemplate="{TemplateBinding ContentTemplate}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

EDIT based on comments: Adding clarification- I tried using Pressed prior to posting this question but it doesn't do what I'm looking for. After click I want the color to remain applied until another button is clicked, then the text in the new button clicked will change color and the previous button clicked will go back to the default color. With pressed, as soon as you let the mouse button go the text goes back to default.

Edit based Answer suggestions: Also providing surrounding code to see if mistake is being made somewhere else.

    <Page.Resources>
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="FontWeight" Value="Normal" />
        <Setter Property="UseSystemFocusVisuals" Value="False" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>

                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="ContentPresenter.FontWeight" Value="Bold" />
                                    </VisualState.Setters>
                                </VisualState>

                                <VisualState x:Name="Pressed"/>

                                <VisualState x:Name="Disabled">
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Focused">
                                    <VisualState.Setters>
                                        <Setter Target="ContentPresenter.Foreground" Value="Purple" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Unfocused" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter x:Name="ContentPresenter"
                      Content="{TemplateBinding Content}"
                    ContentTransitions="{TemplateBinding ContentTransitions}"
                    ContentTemplate="{TemplateBinding ContentTemplate}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Button Style="{StaticResource ButtonStyle}" Content="Button" HorizontalAlignment="Left" Margin="10,180,0,0" VerticalAlignment="Top" />
    <Button Style="{StaticResource ButtonStyle}" Content="Button" HorizontalAlignment="Left" Margin="100,180,0,0" VerticalAlignment="Top"/>
    <Button Style="{StaticResource ButtonStyle}" Content="Button" HorizontalAlignment="Left" Margin="194,180,0,0" VerticalAlignment="Top"/>
</Grid>
Gema Beltran
  • 171
  • 9
  • This is UWP and not WPF. – mm8 Aug 08 '17 at 09:31
  • I don't think that `Focused` visual state should be applied on click. It's the `Pressed` visual state you want to modify to change color on click. – Marian Dolinský Aug 08 '17 at 14:32
  • @MarianDolinský I tried using Pressed prior to posting this question but it doesn't do what im looking for. After click I want the color to remain applied until another button is clicked, then the text in the new button clicked will change color and the previous button clicked will go back to the default color. With pressed, as soon as you let the mouse button go the text goes back to default. – Gema Beltran Aug 08 '17 at 16:32

1 Answers1

5

In UWP, there's a System-level focus visual applied to Button and a lot of other controls by default. If you want to manage your own focus visual like how you defined in your Focused visual state, try setting

<Setter Property="UseSystemFocusVisuals" Value="False" />

in your style.

Also, custom focus visual state is not inside CommonStates but FocusStates. So you will need to move your focus state inside

<VisualStateGroup x:Name="FocusStates">
    <VisualState x:Name="Focused">
        <VisualState.Setters>
            <Setter Target="ContentPresenter.Foreground" Value="Purple" />
        </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="Unfocused" />
</VisualStateGroup>

Update

When you want to maintain the focus on click, you will want two things. First, you need AllowFocusOnInteraction set to True. By default, it's already True on a Button. Second, you want to handle PointerFocused state along with Focused one. So replace your focus states with the following

<VisualStateGroup x:Name="FocusStates">
    <VisualState x:Name="Focused">
        <VisualState.Setters>
            <Setter Target="ContentPresenter.Foreground" Value="Purple" />
        </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="PointerFocused">
        <VisualState.Setters>
            <Setter Target="ContentPresenter.Foreground" Value="Purple" />
        </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="Unfocused" />
</VisualStateGroup> 

Why? Because two states are happening around the same time when you click a Button - Pressed from CommonStates and PointerFocused from FocusStates. The Focused state is generally triggered when you tap the Tab key.


<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="FontWeight" Value="Normal" />
    <Setter Property="FontSize" Value="40" />
    <Setter Property="UseSystemFocusVisuals" Value="False" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />

                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="FocusContentPresenter.FontWeight" Value="Bold" />
                                    <Setter Target="ContentPresenter.FontWeight" Value="Bold" />
                                    <Setter Target="ContentPresenter.Foreground" Value="Pink" />
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Pressed">
                                <VisualState.Setters>
                                    <Setter Target="ContentPresenter.Foreground" Value="Purple" />
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Disabled">
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <VisualState.Setters>
                                    <Setter Target="FocusContentPresenter.Foreground" Value="Purple" />
                                    <Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="PointerFocused">
                                <VisualState.Setters>
                                    <Setter Target="FocusContentPresenter.Foreground" Value="Purple" />
                                    <Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Unfocused" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" />
                    <ContentPresenter x:Name="FocusContentPresenter" Opacity="0" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Justin XL
  • 38,763
  • 7
  • 88
  • 133
  • I implemented your suggestion, still not seeing anything happen. I added more context to the question above and plus a code snipped that includes your suggestion and the surrounding code. Still cant get this to work as desired. – Gema Beltran Aug 08 '17 at 20:12
  • That works perfect! Its one step closer to what I need, except that on "PointerOver" I'm expected to have the color change to a different color, say pink. So on click color is purple and on "PointerOver" color is pink. With this solution when i change the color on pointer over it overwrites the color set by "PointerFocused" and "Focused". How can I get "PointerOver" to not change the button on focus? – Gema Beltran Aug 08 '17 at 23:13
  • umm...PointerOver is still reseting the purple color set by PointerFocused and Focused. After you click if you leave the cursor over the button you clicked the color goes back to pink – Gema Beltran Aug 09 '17 at 00:12
  • 1
    If you want a different color on press, just change the color from pink to purple in Pressed state. Basically, when your mouse cursor enters the button, PointerOver is raised, then, when you click, Pressed raised for a short amount of time and followed by PointerFocused. Make sense? – Justin XL Aug 09 '17 at 00:16
  • Yeah, it makes sence, but i think thats happening is a little more than that. When the mouse cursor enters the button, PointerOver is raised, then, when you click, Pressed raised for a short amount of time and followed by PointerFocused followed by PointerOver again if the cursor is till over the button, if you move the cursor away from the button you can see that PointerFocused was applied, but as soon as you move the cursor back into the button then PointerOver is applied again..the ultimate goal is to keep PointerOver from applying where there was a PointerFocus – Gema Beltran Aug 09 '17 at 00:27