Loïc Neiger
Loïc Neiger

Reputation: 1

XAML UWP focus background on custom button

On a XAML UWP application, Ive a class extending Button. I've setted a Background ImageBrush.

My problem is that when my buttons get the focus or on the mouseover event, a grey rectangle bordered with black appear on my button.

I've tried a shitton of many solution, from changing foreground to modifying FocusVisualPrimary/SecondaryBrush on various kind of event (gotFocus, mouseEntered, mouseover). Nothing worked, the best result I got was with setting button.Background = "originalBitmapImage" on mouseover event (I created a new ImageBrush with the same image path as the original background then attributed it to BackGround), but the image is all flickering when mouseover is fired (as it reload a new image each time).

Here is an picture showing the problem (left : normal button, right : same button with mouseover) :

Demo

I would like to keep the same image in the two case, I'm a bit at loss about how to do this.

public class MyButton : Button 
{

private static string Image_path = "ms-appx:///assets/Button.png";

        public MyButton()
        {

            ImageBrush brush = new ImageBrush()
            {
                ImageSource = new BitmapImage(new Uri(MyButton.Image_path))
            };
            this.Background = brush;

            this.PointerEntered += a;

        }

        // This almost work, but the image is flickering when event is fired
        private void a(object sender, PointerRoutedEventArgs e)
        {
            ImageBrush brush = new ImageBrush()
            {
                ImageSource = new BitmapImage(new Uri(MyButton.Image_path))
            };
            //this.Foreground = brush;
            this.Background = brush;
        }
}

Upvotes: 0

Views: 1069

Answers (2)

Loïc Neiger
Loïc Neiger

Reputation: 1

At the end I found a solution : I added style to my 5 types of button to each page of my project. This is not really nice solution as button are created from c# class (code behind) in order to factorises the code, and all style are adding 500+ code line for simple image modification on mouseover....

I used this kind of styling :

'

    <Style TargetType="local:MyButton">
        <!--<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />-->
        <Setter Property="Padding" Value="8,4,8,4" />
        <!--<Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />-->
        <Setter Property="UseSystemFocusVisuals" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:MyButton">
                    <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
                                               Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
                                               Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                               Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter x:Name="ContentPresenter"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Content="{TemplateBinding Content}"
                      ContentTransitions="{TemplateBinding ContentTransitions}"
                      ContentTemplate="{TemplateBinding ContentTemplate}"
                      Padding="{TemplateBinding Padding}"
                      HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                      VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                      AutomationProperties.AccessibilityView="Raw"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Page.Resources>'

Upvotes: 0

Jayden
Jayden

Reputation: 3286

We can copy the default style of the Button then we can edit the PointerOver of VisualState in the Template.

From the default style, it set ButtonBackgroundPointerOver ThemeResource to the Background of the Button in the PointerOver VisualState. So we can define the ButtonBackgroundPointerOver in the page's resources that without editing the style of the Button.

For example:

<Page.Resources>
    <StaticResource x:Key="ButtonBackground" ResourceKey="MyMyImageBrush" />
    <StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="MyMyImageBrush" />
    <StaticResource x:Key="ButtonBackgroundPressed" ResourceKey="SystemControlBackgroundBaseMediumLowBrush" />
    <ImageBrush x:Key="MyMyImageBrush" ImageSource="ms-appx:///assets/Button.png" />
</Page.Resources>

Upvotes: 1

Related Questions