This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 44213 - Can't bind to specific properties through OnPlatform
Summary: Can't bind to specific properties through OnPlatform
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms (show other bugs)
Version: 2.3.2
Hardware: PC Windows
: --- enhancement
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-09-12 18:46 UTC by Clint
Modified: 2017-02-01 18:12 UTC (History)
4 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Clint 2016-09-12 18:46:18 UTC
It would be great if we could do OnPlatform binding to specific properties of a control.
It would at least give a way to band-aid this other bug:
https://bugzilla.xamarin.com/show_bug.cgi?id=43664

Let's say you have an ```Entry```, and you want to bind the ```HeightRequest``` with platform-specific values which themselves are bindings.

So not this kind of simple hard-coded values:
```xml
                  <Entry>
                    <Entry.HeightRequest>
                      <OnPlatform x:TypeArguments="x:Double">
                        <OnPlatform.iOS>40</OnPlatform.iOS>
                        <OnPlatform.Android>60</OnPlatform.Android>
                      </OnPlatform>
                    </Entry.HeightRequest>
                  </Entry>
```

but something dynamic more like this:
```xml
                        <Entry.HeightRequest>
                            <OnPlatform x:TypeArguments="x:Double">
                                <OnPlatform.iOS>
                                    <Binding Converter="{StaticResource TimesxConverter}"
                                             ConverterParameter="1.25"
                                             Path="FontSize"
                                             Source="{x:Reference MyEntryControl}" />
                                </OnPlatform.iOS>
                            </OnPlatform>
                        </Entry.HeightRequest>
```
What this would do is take the ```FontSize``` of the ```MyEntryControl```, run it through a converter to get a value * 1.25, then use that result as the ```HeightRequest```.
Problem: This throws a run-time exception of TypeMismatch between ```Binding``` and ```System.Double```.  In other words it doesn't seem to accept that the binding can return a double.

The converter and binding works if not use with OnPlatform:
```xml
                                <Entry x:Name="MyEntryControl"
                                       HeightRequest="{Binding Path=FontSize,
                                                               Source={x:Reference MyEntryControl},
                                                               Converter={StaticResource TimesxConverter},
                                                               ConverterParameter=1.25}"
                                       Placeholder="Pro"
                                       PlaceholderColor="Gray"
                                       Text="{Binding StockNumber}"
                                       Style="{StaticResource EntryStyleLrg}" />
```
Comment 1 Rui Marinho 2016-10-04 18:25:19 UTC
Why dont you check on your converter or view model?
Something like

> if(Device.OS == TargetPlatform.iOS)
Comment 2 Rui Marinho 2016-10-04 18:31:18 UTC
This s a new feature request and will be added to our backlog. 

Thanks.
Comment 3 Clint 2016-10-04 18:34:52 UTC
Using a converter is a band-aid for the actual problem, which is that we can't bind properties directly within OnPlatform in XAML.

Additionally, if we can't supply a value from the XAML then the converter would have to be hard-coded and not be very reusable.  I might need a scale factor of 1.25 for one control and 2.50 on another. 


As for ViewModel - We're talking about the UI... ViewModel shouldn't know anything about UI; that would be a complete violation of MVVM design patterns. 

Thank you for adding it as a feature request
Comment 4 Stephane Delcroix 2017-01-24 13:17:13 UTC
the proposed XAML is invalid, as that would mean the OnPlatform object is the target of the binding to double.

but this makes sense to support:

<OnPlatform x:TypeArguments="BindingBase">
  <OnPlatform.iOS>
    <Binding Converter="{StaticResource TimesxConverter}"
             ConverterParameter="1.25"
             Path="FontSize"
             Source="{x:Reference MyEntryControl}" />
  </OnPlatform.iOS>
</OnPlatform>

That'd mean the OnPlatform returns one Binding or the other depending on the platform.

I made the required change to support that in https://github.com/xamarin/Xamarin.Forms/pull/709
Comment 5 Clint 2017-01-24 13:26:34 UTC
@Stephane.Delcroix

That's wonderful.  Thank you!
Comment 6 Clint 2017-01-24 13:27:56 UTC
OH... Any guess when that might make its way to a stable update of Xamarin.Forms?  I don't get to use 'experimental' code at work.  If its not in the official update we don't put it in product code.
Comment 7 Samantha Houts 2017-02-01 18:12:25 UTC
Should be fixed in 2.3.5-pre1. Thank you!

Note You need to log in before you can comment on or make changes to this bug.