Forum Xamarin.Forms

Treat 'null' as a valid value for CommandParameter, Converters, and other places where it is ignored

ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

Summary

In CommandParameter and ConverterParameter if the parameter supplied evaluates to null the converter is never executed and the command's CanExecute is not evaluated or honored.
BugZilla #51147, #46603
In one of the replies to one of those bugs Stephane Delcroix stated it was "by design". That is an unacceptable stance and contrary to existing WPF/C#/XAML/MVVM design and use. null is a perfectly valid value and one developers use a lot in their logic and in their bindings. Pretending it isn't a valid value will keep LOTS of existing code from not being migrate-able into Xamarin.

API Changes

Stop ignoring null and pass it through to commands and converters, letting that code do its job to evaluate a response. Not more: Just stop filtering it.

                        <!--#region Accept button-->
                        <Button Grid.Row="4"
                                HorizontalOptions="FillAndExpand"
                                VerticalOptions="FillAndExpand"
                                BackgroundColor="Green"
                                Command="{Binding ScoobyCommand}"
                                CommandParameter="{Binding SelectedDocument.DocumentType}"
                                FontSize="{StaticResource MediumFontSize}"
                                IsVisible="{Binding AutoAccept,
                                                    Converter={StaticResource BoolInvertConverter}}"
                                Text="{StaticResource Accept}"
                                Style="{StaticResource ButtonStyleLrg}" />
                        <!--#endregion Accept button-->

In this example if CommandParameter SelectedDocument.DocumentType has a value then the button is enabled.
If DocumentType later becomes null then the button should then disable. But it doesn't because nulls are getting filtered and not treated as a valid value.
End result is this button gets enabled when the DocumentType is set to a non-null value, then remains enabled for the lifecycle of the app . Clearly that was not expectation of the developer nor the user.

Intended Use Case

You want a button enabled when you have a object, and disabled when you don't.

Expectation:
When you set an object to a non-null value the Command CAN execute and the button enables.
When you set an object to null the command CANNOT execute and the button disables.

Actually happening:
When you set the object to a non-null value the button enables.
When you set the object to null the evaluation just doesn't take place, so the button remains enabled.

Tagged:

Open · Last Updated

Posts

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    I'd gladly second this proposal, but I think we already support it. If the property targeted by the binding path is null, that null shouldn't be filtered. If it's not the case, it doesn't even require a new proposal, a simple bug report would suffice.

    The 'by design' answer on https://bugzilla.xamarin.com/show_bug.cgi?id=46603 apply to something completely different, which is not covered by this proposal: if the binding path can not be resolved, we do not apply the binding. That is, we do not treat "Foo.Bar" as "Foo?.Bar". But this is totally unrelated to the proposal at hand.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited December 2016

    @StephaneDelcroix Glad to see you jump in.

    I'd gladly second this proposal, but I think we already support it.

    You don't. That's why I spent 2 full work days trying to figure out WTF was going on, resulting in the Bugzilla report and its inclusive screen shots. To get around the bug of ignoring the null (once I suspected that was the issue) I then had to create a bool property that simply return !DocumentType == null; and a couple other places that raised an extra RaisePropertyChanged (()=>DocumentType; to force re-evaluation. It works. It gets the job done. But its still a cludgy band-aid.

    The 'by design' answer {...} apply to something completely different,

    The two items may not be related, but they sure feel related from a developer standpoint. It feels as if null is not considered an acceptable value by Xamarin because of the way it is treated in more than once place within the ecosystem. Maybe one of those points is a bug, and one is 'by design', and that leads to a false perception from those of us on the outside. But that then opens another issue: Consistency. If null is a valid value for one thing (CommandBinding) but not a valid value for ConverterParameter people are going to get even more confused.

    As for #46603 let me give you a simple use case where the 'by design' falls down:
    Let's say I want one control visible if a property evaluates to true after coming through my converter, and I want a different control hidden based on the same property. For example if the property is male/female I would hide 'are you pregnant' and show 'have you had a prostate exam'.
    Get what I'm saying: When control A is visible control B won't be; because they both use the same property (maybe an enum) and one goes through a straight converter and one goes through an invert version of that converter.
    Any sane person would expect under those conditions one control is going to be visible and one isn't no matter what: Just has to be if its the same property and one is an invert converter. - But since the property is null the converter is never executed in either case leaving both controls visible. Nobody with years of WPF experience would expect that. Lots and lots of existing code breaks if you migrate it to Xamarin because of this.

    Proposed fix

    Instead if the property is null you send the null to the converter anyway. Make it the developer's responsibility to write code to handle that situation. if male return blue, if female return pink, if null log error and display popup

    My proposal is not just to fix the one bug in the CommandParameter issue... (but please do that straight away if its as easy as you make it sound). But to be consistent throughout Xamarin in taking null as a valid value that gets passed and binded in all cases, all uses throughout the Xamarin ecosystem.

    Xamarin is Microsoft now, right? Shouldn't things work same-same as much as possible with the 10+ years of C#/XAML/MVVM evolution that already exists and that developers are already familiar with? Xamarin can really no longer pretend all of that doesn't exist or all those WPF developers don't exist. They are your strongest and most experienced developers that are migrating to Xamarin now. Its not just whackers at their kitchen tables. Now that Xamarin is part of MSDN and Visual Studio there are hordes of WPF developers at the Xamarin gates.

    I get that StackLayout versus StackPanel help avoid clashes and conflicts between high-level namespaces and keep 3rd party tools such as ReSharper from making bad suggestions. But foundation concepts such as "A null binding is passed through" in WPF and "A null binding halts evaluation" in Xamarin causes developers a lot of heartache and make life hard for those of use trying to use what you're creating. Making life hard for the users does not promote the global domination by Xamarin that I for one would love to see.

Sign In or Register to comment.