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

[Bug] [Regression] UWP Button breaks the Layout #14768

Merged
merged 5 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>