Is it possbile to bind a specific property value with OnProperty?

ClintStLaurentClintStLaurent ✭✭✭✭✭USUniversity ✭✭✭✭✭

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:

                  <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:

                        <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:

                                <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}" />

Does anyone know a way/syntax for binding specific properties? Otherwise I have to bind adding entire controls through OnPlatform with minor variations per-platform and that's just 'hacky'.

Answers

  • JulienRosenJulienRosen ✭✭✭✭ CAMember ✭✭✭✭
    edited September 2016

    just a suggestion, but couldn't you bind like normal and figure out the appropriate values based on the device in code behind? That way you'd only need the one control.

    The type mismatch is occurring because it's trying to find a double, and it's finding a binding instead. Your converter isn't even getting called. You can't just replace 40 with <Binding .. />

  • ClintStLaurentClintStLaurent ✭✭✭✭✭ USUniversity ✭✭✭✭✭

    Thanks for the reply.

    couldn't you bind like normal and figure out the appropriate values based on the device in code behind?

    That's still 'hacky', just in a different direction. Besides the value for this instance isn't based on the device. Its based on values set up in styles. So if the style says the font is size 36 then the converter does the math making the Entry.HeightRequest 1.5*36 = 54. But a different style would be font size of 24. So the code behind becomes more complicated needing to become aware of the style, look up its values etc., than just duplicating the control through OnPlatform: Once with the converter for iOS and once without for Android.

    The type mismatch is occurring because it's trying to find a double, and it's finding a binding instead. Your converter isn't even getting called. You can't just replace 40 with

    Yes, I understand the why of it as stated that in the original question. I was hoping someone might know a way around the limitation, or a different syntax for the binding that avoids the bug. And that's what it is to me: A bug. As a property it should be bindable, and seeing a binding this should attempt to resolve the binding instead of just giving up and throwing a type mismatch. Which is why I reported it as a bug on Xamarin bugzilla in addition to posting the question.

  • DerProgrammiererDerProgrammierer ✭✭✭ DEMember ✭✭✭
    edited October 2016

    @ClintStLaurent did you find a way to use dynamic binding in OnPlatform?

    I'm trying to do this:

    <OnPlatform x:Key="RightBubbleDetailFontColor" x:TypeArguments="Color" iOS="{DynamicResource rightBubbleDetailFontColor}" Android="{DynamicResource rightBubbleDetailFontColor}" WinPhone="{StaticResource rightBubbleDetailFontColor}"> </OnPlatform>

    Unfortunately it's not working and I get this error when I try to start debugging:

    Object reference not set to an instance of an object

  • ClintStLaurentClintStLaurent ✭✭✭✭✭ USUniversity ✭✭✭✭✭

    @DerProgrammierer No, I never found a syntax to do that cleanly. Instead I made a MultiBinding converter for my need then check the OS within the C# as part of doing the convert. I'm not thrilled with it, but its reliable and human-readable and easy for other developers in my team to follow what's happening.

  • DerProgrammiererDerProgrammierer ✭✭✭ DEMember ✭✭✭
    edited October 2016

    @ClintStLaurent Okay. As you see in my code, I don't really need to convert my data. Do I still have to use the MultiBinding converter? If so, is it possible for you to show me how you implemented it?

    Thank you in advance.

  • ClintStLaurentClintStLaurent ✭✭✭✭✭ USUniversity ✭✭✭✭✭

    I can... But I won't have the free time to work up a sample application until the weekend.

  • ClintStLaurentClintStLaurent ✭✭✭✭✭ USUniversity ✭✭✭✭✭

    FYI: The Bugzilla I filed for this a while back has been confirmed and tagged as "New Feature Request" as of today.
    https://bugzilla.xamarin.com/show_bug.cgi?id=44213

Sign In or Register to comment.