Join GitHub today
[C] new OnPlatform mechanism #658
Description of Change
Implement the change proposed in https://forums.xamarin.com/discussion/84632/redesign-onplatform
C# code should be ported to this:
New xaml syntax looks like this:
(note: I tested it, it actually works with emojis as platform names. Be creative.)
none. but allow 3rd party platforms
All Tizen overrides. Not published in any release yet.
changed the title from
[C] Obsolete TargetPlatform
[C] new OnPlatform mechanism
Dec 22, 2016
Jan 12, 2017
5 of 6 checks passed
@gtbuchanan we went for non-generic
As for the conversion issue, please file an issue and I'll look at it
I agree that the loss of type safety seems to be a step in the wrong direction.
var menuButtonSize = (OnPlatform<double>)Application.Current.Resources["MenuButtonSize"]; return new GridLength(Device.OS == TargetPlatform.iOS ? menuButtonSize.iOS : menuButtonSize.Android);
And look at the amount of type casts I have to do now (please correct me if this can be done in a better way):
var menuButtonSize = (OnPlatform<double>)Application.Current.Resources["MenuButtonSize"]; var v = menuButtonSize.Platforms.First(p => p.Platform.First().Equals(Device.RuntimePlatform)).Value; return new GridLength(double.Parse((string)v));
Is this intended? It doesn't feel right writing this code.
The xaml is also slightly more verbose now, it has gone from this:
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="60" x:Key="MenuButtonSize" />
<OnPlatform x:TypeArguments="x:Double" x:Key="MenuButtonSize"> <On Platform="iOS">40</On> <On Platform="Android">60</On> </OnPlatform>
I don't mind the slightly more verbose xaml, but I don't really like the loss of type safety.
Thanks... Not sure if I like it new way. I have projects where I target all 3 major platforms, and combination of Device.OnPlatform and Device.Idiom did the job for me. Why fixing things which were fit to purpose in 99% of scenarios? At least, please remove "deprecated" warning for now. You've touched one of the sensitive areas in cross-platform design, so I guess it would be wise to give us "old timers" a bit more time to get used to the change. Or challenge it all the way back to where it was.
How would I set a default value in xaml? I have tried:
But neither work?
added a commit
this pull request
Apr 19, 2017
@brianlagunas According to the original thread the reasoning is:
Personally, I think this solution as implemented is far worse than the stated problem above.
There are a finite number of platforms even into the forseeable future (eg, Tizen, MacOS) and adding a handful of new entries to the enum over time seems eminently reasonable.
Also, for 3rd parties you could just add a "release-valve"
Totally agree there are a finite number of new platforms, and I would say there doesn't need to be a requirement that the Platform implementation should have to be part of the Xamarin Forms repository like Tizen. That said magic string seems more error prone than to simply require Tizen or whoever to submit a PR adding their platform to an OS/RuntimePlatform enum. Think of it like a developer adding their RSS feed to Planet Xamarin. Not to mention somehow we ended up with
I have a feeling that the developer experience was not considered when creating this API. Meaning the API was not used in a production app scenario, but instead created from inside a sandbox. I'm assuming/hoping there is some technical reason why this was a string and not Enum. Otherwise it's just a poor coding practice.
In a scenario like this:
What would be the best way to rewrite this given this new API? I'm finding that it requires a switch statement outside of the scenario to store the Thickness property to then apply it in the Content construction:
Or am I just missing something easy? /crossesfingers
I don't agree with strings instead of a type and losing type safety. Also, I don't see anywhere mentioned what happens if the platform string is misspelled.
Is this how default should work in the new way? Because it is not working at the moment:
<Label Text="This should be the default"> <Label.Text> <OnPlatform x:TypeArguments="x:String"> <On Platform="iOS">iOS</On> </OnPlatform> </Label.Text> </Label>
If I run this sample on Android, the text is empty.
@akamud no what you are doing is overriding the Text Value, not setting a default. While there are some arguments that the new OnPlatform is more extensible, it wasn't fully thought out. The current releases would require that you specify the platform otherwise you effectively get