Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] UWP Button BackgroundColor turns gray when hovering #9123

Open
MhAllan opened this issue Jan 8, 2020 · 12 comments
Open

[Bug] UWP Button BackgroundColor turns gray when hovering #9123

MhAllan opened this issue Jan 8, 2020 · 12 comments
Labels
e/3 🕒 3 in-progress This issue has an associated pull request that may resolve it! m/high impact ⬛ p/UWP t/bug 🐛
Milestone

Comments

@MhAllan
Copy link

MhAllan commented Jan 8, 2020

Description

UWP Button BackgroundColor turns gray when hovering on it while targeting builds: 17763 and 18362, problem doesn't appear in creators update (16299)

Steps to Reproduce

  1. Create a XF button with background color
  2. target UWP 17763 or 18362
  3. hover on the button

Expected Behavior

Button preserves its background color (similar to what we get when targeting version 16299)

Actual Behavior

Button turns to gray (or whatever default theme)

Basic Information

  • UWP: SDK versions: 17763 and 18362

Workaround

In UWP App.Xaml Resources:

<Style x:Key="ButtonStyle" TargetType="Button">
				<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">
											<Storyboard>
												<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
											</Storyboard>
										</VisualState>
										<VisualState x:Name="PointerOver">
											<Storyboard>
												<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 SystemControlDisabledBaseLowBrush}" />
												</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>

Then create UWP button renderer

 public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                var style = Application.Current.Resources["ButtonStyle"] as Style;
                Control.Style = style;
            }
        }
}
@MhAllan MhAllan added s/unverified New report that has yet to be verified t/bug 🐛 labels Jan 8, 2020
@hartez hartez added p/UWP e/3 🕒 3 and removed s/unverified New report that has yet to be verified labels Jan 9, 2020
@samhouts samhouts added the in-progress This issue has an associated pull request that may resolve it! label Jan 23, 2020
@juanmalm
Copy link

juanmalm commented May 4, 2020

Is this issue planned to be fixed?

@mnxamdev
Copy link

We are having this issue too. We're trying to get get a Windows release out using shared code from our Android and iOS apps. Please help Xamarin! I'd be happy with a workaround.

@MhAllan
Copy link
Author

MhAllan commented May 22, 2020

@mnxamdev I updated the issue with my workaround, hope it works for you. don't forget to export your renderer

@mnxamdev
Copy link

mnxamdev commented May 22, 2020

Beat me to it @MhAllan ! This was a real pain to figure out. I too had to create a custom control template too except all I did was add an empty PointerOver visual state. I'm unclear though if I need to add additional {TemplateBinding X} to respective properties to make sure all properties are bound on the consumed/declared button:

<ControlTemplate x:Key="DefaultButtonControlTemplate" TargetType="Button">
        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="PointerOver"/>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <ContentPresenter 
                x:Name="ContentPresenter" 
                AutomationProperties.AccessibilityView="Raw" 
                BorderBrush="{TemplateBinding BorderBrush}" 
                BorderThickness="{TemplateBinding BorderThickness}"
                ContentTemplate="{TemplateBinding ContentTemplate}" 
                ContentTransitions="{TemplateBinding ContentTransitions}" 
                Content="{TemplateBinding Content}" 
                HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                Padding="{TemplateBinding Padding}" 
                VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" 
                TextWrapping="WrapWholeWords"/>
        </Grid>
    </ControlTemplate>
    public class UWPButton : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control button = Control;
                var template = Windows.UI.Xaml.Application.Current.Resources["DefaultButtonControlTemplate"] as ControlTemplate;
                button.Template = template;
            }
        }
    }

@holecekp
Copy link

@MhAllan Thank you very much for your workaround. It works also for ImageButton.

@samhouts samhouts added this to the 5.0.0 milestone Aug 13, 2020
@samhouts samhouts removed this from the 5.0.0 milestone Nov 2, 2020
@PureWeen PureWeen added this to the 5.0.1 milestone Nov 5, 2020
@jfversluis
Copy link
Member

I see some workarounds and I think we did some fixes in this area, closing this one for now, let me know if this is still an issue to anyone! Thanks!

@dag23
Copy link

dag23 commented Dec 11, 2021

@jfversluis It was fixed in 5.0.0.2083 but it's a problem again in 5.0.0.2244.

@snakebytetech
Copy link

snakebytetech commented Dec 20, 2021

An update (12/21/2021)....I'm not exactly which thing I did was what fixed it, but my issue where the "active" color is removed and doesn't come back is now working again. I was testing the various previous versions of Xamarin.Forms, but I'm back to the current of 5.0.0.2291. I think what may have fixed it was I cleaned the solution, I opened the directory of my shared project and UWP projects and deleted the obj/bin folders, then rebuilt the solution and restarted VisualStudio 2022. Try that to see if it helps. Note, my buttons still change on hover to show an outline of a button which isn't really what I want either, but at least my active color comes back. I also reverted put my target and min version for UWP back to 1903/18362. Unfortunately, everything else I mention below is still a problem.

This is still a problem for me as well as other layout issues when I upgraded Xamarin.Forms from 5.0.0.2012 to 5.0.0.2291. I'm targeting UWP for now, Minimum version = 17763 and target = 18362. I also updated a handful of other Nugets.

This latest update messed up the layout for multiple objects.

  • Switches (hover them and they disappear because of white-on-white and there's a huge gap between the switch and a label I have next to it which wasn't there before.
  • Buttons as explained above.
  • Stacklayouts center everything and won't recognize when I explicitly give it the default HorizontalOption of "Start".
  • Labels which didn't wrap before now wrap making things look horrible.

Before the upgrade to the latest Xamarin.Forms, this screenshot below looked nice and well layed out. You can see how labels are scrunched with a bunch of space between switches and labels. Note, I have a custom renderer for the switch to hide the on/off text because the words on/off are redundant. I tried removing my renderer and that didn't help. The words to the right of the switches are supposed to be what is right next to the switch. Instead, there is a big gap between the switch and the label now. That wasn't there before.

2021-12-20_16-03-33

Since this thread is about the button, I'm not only experiencing the same as above, but I use buttons as a navigation so I can use Windows shortcut keys and when you click one, it'll make the text color of that button "active". Now, when you hover that button, the "active" color goes away. The only way to get it back is to click it again.

It's as though you forgot about light themes and UWP apps and only tested your releases with dark themes on Android and iOS.

Please help. I don't want to have to go back into every one of my pages to re-design them and change my background so the hover "feature" doesn't ghost out my controls. At this point, if there's not a fix/suggestion soon, I'm probably going to downgrade my Xamarin.Forms and cross my fingers you fix it with the next release because I don't have the time to mess with something like this right now.

@snakebytetech
Copy link

Another update. It seems the spacing problem was caused by my Switch Renderer is no longer supported. I like the new version better and perhaps it's how I should have originally written it. Hopefully it helps someone else experiencing similar problems.

image

image

@dag23
Copy link

dag23 commented Dec 31, 2021

I have investigated and the template of the FormsButton does not contain a Grid.
b85c28e#diff-489c1b3b032afaa3b926f0420f2d644b2faabe1d5008d278e10b6fb5feccbd28
The ButtonRenderer is searching for one to use the InterceptVisualStateManager.
https://github.com/xamarin/Xamarin.Forms/blob/5.0.0/Xamarin.Forms.Platform.UAP/ButtonRenderer.cs
So it doesn't hook the InterceptVisualStateManager and we can't override the Visual States for the Button in Xamarin.Forms styles.

@jfversluis
Copy link
Member

Hey everyone, thanks for all the input here. I see a lot of things that might or might not be related, but just to be sure; this is still (or again) an issue in the latest stable version 5.0.0.2291? But it was fixed in an earlier version?

Seems like this PR #13148 might have something to do with it?

@dag23 besides doing the research do you also have a proposal on how to fix it?

@bobwhitten
Copy link

I have this issue, and I've not had success yet with a workaround. I'm running 5.0.0.2478 (latest, as of this writing), and target version is build 19041 (Win 10, version 2004). For me, this is difficult because I have a dark background, and some white buttons with black text. So, it almost disappears. Disabled is even more.

The iOS behavior for this is just fine (changes opacity, I think, of text).

I don't want to spend too long on this -- this latecomer app will probably move over to MAUI pretty soon.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
e/3 🕒 3 in-progress This issue has an associated pull request that may resolve it! m/high impact ⬛ p/UWP t/bug 🐛
Projects
None yet