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

Commit

Permalink
[Bug] [Regression] UWP Button breaks the Layout (#14768)
Browse files Browse the repository at this point in the history
* Fix hover and focus

* Revert ButtonRenderer change

* Fix build

* Fixed sample bindings

* Fix the Layout issue in the Button

Co-authored-by: Javier Suárez Ruiz <javiersuarezruiz@hotmail.com>
  • Loading branch information
jfversluis and jsuarezruiz committed Oct 21, 2021
1 parent 6995d31 commit 3ea7886
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Windows.Input;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 14764, "[Bug] [Regression] UWP Button breaks the Layout", PlatformAffected.UWP)]
public class Issue14764 : TestContentPage
{
bool _isVisible;

public bool IsButtonVisible
{
get => _isVisible;
set
{
if (_isVisible == value)
return;

_isVisible = value;
OnPropertyChanged();
}
}

protected override void Init()
{
var grid = new Grid
{
BackgroundColor = Color.AliceBlue
};

grid.AddRowDef(type: GridUnitType.Auto, count: 4);
grid.AddRowDef(type: GridUnitType.Star, count: 1);

var button1 = new Button
{
Text = "Toggle Visibility"
};

button1.SetBinding(Button.CommandProperty, new Binding("ToggleVisibilityCommand"));

grid.Children.Add(button1, 0, 0);

var button2 = new Button
{
Text = "Button 2",
BackgroundColor = Color.Blue,
TextColor = Color.White
};
button2.SetBinding(IsVisibleProperty, new Binding("IsButtonVisible"));

grid.Children.Add(button2, 0, 1);

var button3 = new Button
{
Text = "Button 3",
BackgroundColor = Color.Yellow
};
button3.SetBinding(IsVisibleProperty, new Binding("IsButtonVisible"));

grid.Children.Add(button3, 0, 2);

var button4 = new Button
{
Text = "Button 4",
BackgroundColor = Color.Red
};
button4.SetBinding(IsVisibleProperty, new Binding("IsButtonVisible"));

grid.Children.Add(button4, 0, 4);

var label = new Label
{
Text = "End alignment",
VerticalOptions = LayoutOptions.End,
HorizontalOptions = LayoutOptions.End,
BackgroundColor = Color.Red
};

grid.Children.Add(label, 0, 5);

Content = grid;
}

public ICommand ToggleVisibilityCommand { get; }

public Issue14764()
{
ToggleVisibilityCommand = new Command(() => IsButtonVisible = !IsButtonVisible);
BindingContext = this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue14426.xaml.cs">
<DependentUpon>Issue14426.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue14764.cs" />
<Compile Include="$(MSBuildThisFileDirectory)RadioButtonTemplateFromStyle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ShellSearchHandlerItemSizing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ShellWithCustomRendererDisabledAnimations.cs" />
Expand Down
6 changes: 6 additions & 0 deletions Xamarin.Forms.Platform.UAP/ButtonRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ protected override void OnElementChanged(ElementChangedEventArgs<Button> e)

void ButtonOnLoading(FrameworkElement sender, object args)
{
// HACK: Update IsNativeStateConsistent to fix issue rendering Buttons inside a CollectionView
var collectionViewParent = Element.FindParent<CollectionView>();

if (collectionViewParent == null)
return;

Element.IsNativeStateConsistent = false;
}

Expand Down
76 changes: 50 additions & 26 deletions Xamarin.Forms.Platform.UAP/Resources.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -356,56 +356,80 @@
<Setter Property="MinWidth" Value="0"/>
</Style>

<!-- override the xamarin forms uwp button style -->
<Style TargetType="uwp:FormsButton">
<Setter Property="Background" Value="{ThemeResource ButtonBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
<Setter Property="Padding" Value="{StaticResource ButtonPadding}"/>
<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="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="-3"/>
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="{StaticResource ButtonPadding}" />
<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="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter
x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw"
Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" CornerRadius="{TemplateBinding CornerRadius}"
ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CornerRadius="{TemplateBinding CornerRadius}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity">
<DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity">
<DiscreteObjectKeyFrame KeyTime="0" Value="0.65"/>
<DiscreteObjectKeyFrame KeyTime="0" Value="0.65" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}"/>
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Expand All @@ -416,5 +440,5 @@
</Setter.Value>
</Setter>
</Style>

</ResourceDictionary>

0 comments on commit 3ea7886

Please sign in to comment.