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

Commit

Permalink
Templated RadioButtons and RadioButtonGroups (#11628)
Browse files Browse the repository at this point in the history
* First stab at RadioButtonGroup attached property and Templated RadioButton

* RadioButtonGroupController assigning group names

* Added updates for RadioButtonGroupController on selection change

* More galleries!

* Content property propagation

* Ignore renderers if using templated views on UWP

* Apply text/font properties to Content

* Make RadioButton template parts constants

* Cache renderer availability lookup

* Add TemplateView check to CreateRenderer on iOS

* Handle Checked RadioButton GroupName changes

* Update WPF renderer

* Update macOS and Tizen renderers

* Add more unit tests, make RB Value updates propagate to RBG

* Remove Text property, updated examples; throw Exception when Content is not Text and non-Text Content is not supported

* Prevent Content exceptions in demo pages

* Colors -> Brushes

* Add default ControlTemplate example

* Set up flags for Core Gallery test pages

* Switch Android back to ToString for Content

* Back to ToString where necessary, and using the WrapperControl for UWP

* Add comment for Content

* Log a nice warning if folks try to use View as Content and it's not supported

* Add experimental flags for drag and drop tests

* Fix crashes due to missing brush experimental flag

* Make control templates from styles work alongside default templates

* Catch up on which flags are still a concern

* Fix infinite loop in platform tests

* Attempt to fix occasionaly GroupableItemsViewController disposed crash

* Make webview visible so we can verify it loaded in UI test screen shots

* Fix merge

Co-authored-by: Rui Marinho <me@ruimarinho.net>
  • Loading branch information
hartez and rmarinho committed Sep 18, 2020
1 parent dacfe47 commit 2a97a6c
Show file tree
Hide file tree
Showing 50 changed files with 1,813 additions and 674 deletions.
2 changes: 2 additions & 0 deletions Stubs/Xamarin.Forms.Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ internal class _ButtonRenderer { }
[RenderWith(typeof(ImageButtonRenderer))]
internal class _ImageButtonRenderer { }

#if !__IOS__
[RenderWith(typeof(RadioButtonRenderer))]
internal class _RadioButtonRenderer { }
#endif

[RenderWith (typeof (TableViewRenderer))]
internal class _TableViewRenderer { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,9 @@
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<ProjectExtensions>
<VisualStudio>
<UserProperties XamarinHotReloadUnhandledDeviceExceptionXamarinFormsControlGalleryAndroidHideInfoBar="True" />
</VisualStudio>
</ProjectExtensions>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

Expand Down Expand Up @@ -36,7 +37,10 @@ protected override void Init()
_webView = new WebView()
{
Source = "https://dotnet.microsoft.com/apps/xamarin",
Cookies = new System.Net.CookieContainer()
Cookies = new System.Net.CookieContainer(),
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
HeightRequest = 600
};

_webView.Navigating += (_, __) =>
Expand Down
1 change: 1 addition & 0 deletions Xamarin.Forms.Controls/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Xamarin.Forms.Controls.GalleryPages.RadioButtonGalleries;
using Xamarin.Forms.Controls.Issues;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration;
Expand Down
4 changes: 4 additions & 0 deletions Xamarin.Forms.Controls/CoreGalleryPages/CoreGalleryPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal class CoreGalleryPage<T> : ContentPage

internal CoreGalleryPage()
{
Initialize();

Layout = new StackLayout
{
Padding = new Thickness(20)
Expand Down Expand Up @@ -55,6 +57,8 @@ internal CoreGalleryPage()
}
}

protected virtual void Initialize() { }

protected virtual void InitializeElement(T element) { }

protected virtual void Build(StackLayout stackLayout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ class RadioButtonCoreGalleryPage : CoreGalleryPage<RadioButton>
protected override bool SupportsTapGestureRecognizer => true;
protected override void InitializeElement(RadioButton element)
{
element.Content = "RadioButton";
}

protected override void Initialize()
{
base.Initialize();
Device.SetFlags(new List<string> { ExperimentalFlags.RadioButtonExperimental });
element.Text = "RadioButton";
}

protected override void OnDisappearing()
Expand All @@ -23,12 +28,12 @@ protected override void Build(StackLayout stackLayout)
{
base.Build(stackLayout);

IsEnabledStateViewContainer.View.Clicked += (sender, args) => IsEnabledStateViewContainer.TitleLabel.Text += " (Tapped)";
IsEnabledStateViewContainer.View.CheckedChanged += (sender, args) => IsEnabledStateViewContainer.TitleLabel.Text += " (Checked Changed)";

var borderButtonContainer = new ViewContainer<RadioButton>(Test.Button.BorderColor,
new RadioButton
{
Text = "BorderColor",
Content = "BorderColor",
BackgroundColor = Color.Transparent,
BorderColor = Color.Red,
BorderWidth = 1,
Expand All @@ -38,7 +43,7 @@ protected override void Build(StackLayout stackLayout)
var borderRadiusContainer = new ViewContainer<RadioButton>(Test.Button.BorderRadius,
new RadioButton
{
Text = "BorderRadius",
Content = "BorderRadius",
BackgroundColor = Color.Transparent,
BorderColor = Color.Red,
BorderWidth = 1,
Expand All @@ -48,101 +53,56 @@ protected override void Build(StackLayout stackLayout)
var borderWidthContainer = new ViewContainer<RadioButton>(Test.Button.BorderWidth,
new RadioButton
{
Text = "BorderWidth",
Content = "BorderWidth",
BackgroundColor = Color.Transparent,
BorderColor = Color.Red,
BorderWidth = 15,
}
);

var clickedContainer = new EventViewContainer<RadioButton>(Test.Button.Clicked,
new RadioButton
{
Text = "Clicked"
}
);
clickedContainer.View.Clicked += (sender, args) => clickedContainer.EventFired();

var pressedContainer = new EventViewContainer<RadioButton>(Test.Button.Pressed,
new RadioButton
{
Text = "Pressed"
}
);
pressedContainer.View.Pressed += (sender, args) => pressedContainer.EventFired();

var commandContainer = new ViewContainer<RadioButton>(Test.Button.Command,
new RadioButton
{
Text = "Command",
Command = new Command(() => DisplayActionSheet("Hello Command", "Cancel", "Destroy"))
}
);

var fontContainer = new ViewContainer<RadioButton>(Test.Button.Font,
new RadioButton
{
Text = "Font",
Font = Font.SystemFontOfSize(NamedSize.Large, FontAttributes.Bold)
Content = "Font",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(RadioButton)),
FontAttributes = FontAttributes.Bold
}
);

var textContainer = new ViewContainer<RadioButton>(Test.Button.Text,
new RadioButton
{
Text = "Text"
Content = "Text"
}
);

var textColorContainer = new ViewContainer<RadioButton>(Test.Button.TextColor,
new RadioButton
{
Text = "TextColor",
Content = "TextColor",
TextColor = Color.Pink
}
);

var paddingContainer = new ViewContainer<RadioButton>(Test.Button.Padding,
new RadioButton
{
Text = "Padding",
Content = "Padding",
BackgroundColor = Color.Red,
Padding = new Thickness(20, 30, 60, 15)
}
);

var isCheckedContainer = new ValueViewContainer<RadioButton>(Test.RadioButton.IsChecked, new RadioButton() { IsChecked = true, HorizontalOptions = LayoutOptions.Start }, "IsChecked", value => value.ToString());

//var checkedVisualState = new VisualState { Name = "IsChecked" };
//checkedVisualState.Setters.Add(new Setter { Property = RadioButton.ButtonSourceProperty, Value = "rb_checked" });

//var group = new VisualStateGroup();
//group.States.Add(checkedVisualState);

//var normalVisualState = new VisualState{ Name = "Normal" };
//normalVisualState.Setters.Add(new Setter { Property = RadioButton.ButtonSourceProperty, Value = "rb_unchecked" });
//group.States.Add(normalVisualState);

//var groupList = new VisualStateGroupList();
//groupList.Add(group);

//var rbStateManaged = new RadioButton() { HorizontalOptions = LayoutOptions.Start };
//VisualStateManager.SetVisualStateGroups(rbStateManaged, groupList);

//var stateManagedContainer = new ValueViewContainer<RadioButton>(Test.RadioButton.ButtonSource, rbStateManaged, "IsChecked", value => value.ToString());

Add(borderButtonContainer);
Add(borderRadiusContainer);
Add(borderWidthContainer);
Add(clickedContainer);
Add(pressedContainer);
Add(commandContainer);
Add(fontContainer);
Add(textContainer);
Add(textColorContainer);
Add(paddingContainer);
Add(isCheckedContainer);
//Add(stateManagedContainer);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ await Device.InvokeOnMainThreadAsync(() => {
protected override async void OnAppearing()
{
base.OnAppearing();

if (_testsRunCount == 0)
{
await Run().ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Xamarin.Forms.Controls.GalleryPages.RadioButtonGalleries.ContentProperties">

<ContentPage.Content>
<StackLayout>
<Label Text="Propagate standard Text properties to Content where applicable:"/>
<Label FontSize="Small" Text="TextColor: Red, CharacterSpacing: 1.5, TextTransform: Lowercase, FontAttributes: Italic, FontSize: 14, FontFamily: BaskerVille"/>
<RadioButton Content="Option A" GroupName="test"
TextColor="Red"
CharacterSpacing="1.5"
TextTransform="Lowercase"
FontAttributes="Italic"
FontSize="14"
FontFamily="Baskerville"
/>
<Label FontSize="Small" Text="TextColor: Blue, CharacterSpacing: 1, TextTransform: Uppercase, FontAttributes: Bold, FontSize: 18, FontFamily: Arial"/>
<RadioButton Content="Option B" GroupName="test"
TextColor="Blue"
TextTransform="Uppercase"
FontAttributes="Bold"
FontSize="18"
FontFamily="Arial"
/>

<Label FontSize="Small" Text="The RadioButton below has its content set to Button (which makes little sense, but this is just an example). Anyway, the Text and Font properties are applied to the Button."/>

<RadioButton GroupName="test"
TextColor="Green"
TextTransform="Uppercase"
FontAttributes="Bold"
FontSize="12"
FontFamily="Arial">

<RadioButton.Content>
<Button Text="It's a button inside a button."></Button>
</RadioButton.Content>

</RadioButton>

<Label FontSize="Small" Text="A Content View which already has these properties set/bound should ignore the RadioButton properties."/>

<RadioButton GroupName="test"
TextColor="Green"
TextTransform="Uppercase"
FontAttributes="Bold"
FontSize="12"
FontFamily="Arial">

<RadioButton.Content>

<Label x:Name="MainLabel" Text="Properties already set."
TextColor="Purple"
TextTransform="Lowercase"
FontSize="Micro"
FontFamily="Baskerville"
FontAttributes="Italic" />


</RadioButton.Content>

</RadioButton>

<RadioButton GroupName="test"
TextColor="Green"
TextTransform="Uppercase"
FontAttributes="Bold"
FontSize="12"
FontFamily="Arial">

<RadioButton.Content>
<Label Text="Properties already bound"
BindingContext="{x:Reference MainLabel}"
TextColor="{Binding TextColor}"
TextTransform="{Binding TextTransform}"
FontSize="{Binding FontSize}"
FontFamily="{Binding FontFamily}"
FontAttributes="{Binding FontAttributes}" />
</RadioButton.Content>

</RadioButton>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Xamarin.Forms.Xaml;

namespace Xamarin.Forms.Controls.GalleryPages.RadioButtonGalleries
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ContentProperties : ContentPage
{
public ContentProperties()
{
InitializeComponent();
}
}
}
Loading

0 comments on commit 2a97a6c

Please sign in to comment.