-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Templated RadioButtons and RadioButtonGroups #11628
Conversation
It's important not to throw an exception in my opinion, the native renderers can just use |
Quite interesting you decided to go with such a breaking change, I remember piles of discussion of "oh, no, we can't do this, it would be a breaking change". Happy to see you're moving forward! |
A case we haven't considered here is what happens if a ControlTemplate is set after the native renderer has already been selected (and is possibly already on screen)? The easy option would be to simply ignore it - is that reasonable? |
That's what the first draft did. The reason for the change was to make it as obvious as possible to the user that what they are trying to do won't work. And to give them an explicit message explaining why (instead of just seeing weird behavior like a RadioButton with a label text of "[Xamarin.Forms.Image]"). The "property order" problem isn't as big here as it would be if we were doing it in Core - we don't have to worry about XAML order or anything like that, because these exceptions don't happen until we've reached the native renderers. By definition, we couldn't be in this stage if ControlTemplate were anything but Can we come up with a concrete example of a situation where this behavior would cause confusion or catastrophe? (That might depend on the outcome of my previous comment), |
When I first read that I didn't catch the "View" part. So would it only throw if you put a view as the content and not other random object or binding? If it's only if you assign a View subclass, then I think the exception is good. But let's say I bind the content to some random object, I would expect it to just ToString it. What I wouldn't want is a scenario like if you use a ListView but forget to put a ViewCell in the DataTemplate and it just doesn't show anything. |
Like I said on Twitter, in my opinion having a specific mandatory order for setting properties otherwise it throws an exception is not a good design. I don’t remember any API in .NET which works like this. |
Beside a warning in device log, having a clear concise comment on the Content property is effective too |
Overall works great. Should this still render text into the ContentPresenter? <RadioButton>
<RadioButton.ControlTemplate>
<ControlTemplate>
<StackLayout Orientation="Horizontal">
<ContentPresenter></ContentPresenter>
</StackLayout>
</ControlTemplate>
</RadioButton.ControlTemplate>
<RadioButton.Content>
Rabbits
</RadioButton.Content>
</RadioButton>
Nothing happens when you change visual at runtime. Visual is such a drastic change with how a field is displayed that it's not a scenario people have ran into. Here's the Issue about it I would default the direction of just doing nothing for now and seeing how people use it. It's weird to switch from the native renderer to the xplat renderer because the radiobutton itself renderers so different. If specifying the ControlTemplate created a completely symmetrical RadioButton then I think it'd make a bit more sense but I feel like you're either going to do one or the other. Here was the PR I had started for visual which would cause elements to recreate It was just a really quick spike but I feel like not worrying about this case for now makes the most sense
If we keep the current behavior I'm a fan of the exceptions. I type the following sentence a lot "did you look at your application output for warnings about bindings?". If I specify an Going the exception route
For the indicators @rmarinho made is so if you specify a template it just uses the xplat indicators and if you don't then it uses the native ones. Would it make sense to follow a similar strategy here? So if I specify <RadioButton>
<RadioButton.Content>
<Image Source="coffee.png"/>
</RadioButton.Content>
</RadioButton> It should just opt in to use the
Do those names come from something? I don't feel like Maybe "Button" and ("CheckedIndicator" or "Checkmark" or "RadioButton") |
I know we had chatted a bit where visual fits into all of this which opens a few other options. @jsuarezruiz, @rmarinho , and I have talked about this a bit with other implementations. For example when @rmarinho first did the indicators he had added a "FORMS" Visual which indicated to the control that it should use xplat instead of platform. We eventually got rid of that for indicators because it didn't really offer a different experience setting the visual to "forms" vs "default" With RadioButton that's a bit different, especially once material and fluent enter the mix. There were a few ideas we've been floating around visual So for RadioButton it would look something like <RadioButton>
<RadioButton.VisualTemplate>
<Forms Content="Text" UncheckedButton="" ControlTemplate="" />
</RadioButton.VisualTemplate>
</RadioButton> <RadioButton>
<RadioButton.VisualTemplate>
<Native Text="Text" />
</RadioButton.VisualTemplate>
</RadioButton> We would still let people specify "Content" on the RadioButton itself but then we could add discoverability of customization this way. |
Hey folks, I am having a look at the basic |
…is not Text and non-Text Content is not supported
783c165
to
4b08b25
Compare
Failing tests were not related. |
Description of Change
Control Templates
[Update: we've moved back to the ToString() behavior instead of exceptions; also, UWP now natively supports arbitrary Forms Views for Content.]
These changes make RadioButton a TemplatedView. This allows for the use of ControlTemplate (to make RadioButton look and behave the same on all platforms), or for the use of a native Renderer (to utilize the native RadioButton control available on platforms which support it).
This also allows for the RadioButton to fall back to the default ControlTemplate on iOS, which does not have a RadioButton control.
The RadioButton no longer has a
Text
property. Instead, it has aContent
property which can be set to string or to arbitrary content. If theContent
property is set to string, that string is used as the displayed text on any native renderers. Any platform using a ControlTemplate will display the string content as a Label.If the
Content
property is set to View, the native renderers which do not support arbitrary content will simply display the result of theToString()
method. ControlTemplates will display the View in theContentPresenter
section of the template. Platforms which support arbitrary content natively (i.e., UWP) will convert the View to a native renderer and display that.So this works on all platforms/renderers:
<RadioButton Content="Option A" />
If we set a ControlTemplate explicitly, we can use arbitrary Views as Content on all platforms:
Setting arbitrary Views as Content without using a ControlTemplate will simply display the string representation. So on Android, the following markup:
Will simply display the string "[Xamarin.Forms.Image]". On UWP, the Forms Image will be converted to a UWP Image and displayed. Because iOS is always using a template for RadioButton - there is no native renderer on that platform - an Image will be displayed.
RadioButtonGroups
These changes also introduce RadioButtonGroup attached properties, which allow any Layout to be turned into a radio button group:
All of the RadioButtons in the StackLayout above will be given the GroupName of "foo" automatically, and will be mutually exclusive.
All of the RadioButtons in the StackLayout above will be give a GroupName based on the bound value of
GroupName
in the BindingContext. TheValue
property of whichever RadioButton is selected will be bound to theSelection
property in the BindingContext.Issues Resolved
None
API Changes
RadioButton is no longer a subclass of Button; rather, it inherits from TemplatedView
Text
propertyContent
propertyValue
propertyAdded class:
public static class RadioButtonGroup
public static readonly BindableProperty GroupNameProperty
public static readonly BindableProperty SelectedValueProperty
Platforms Affected
Behavioral/Visual Changes
None
Before/After Screenshots
Not applicable
Testing Procedure
Control Gallery -> RadioButton Galleries
Also a bunch of unit tests
PR Checklist