microsoft-ui-xaml
microsoft-ui-xaml copied to clipboard
Passing null parameters to x:Bind function binding
This issue has been moved from a ticket on Developer Community.
I'm trying to bind an object using x:Bind function binding. See https://docs.microsoft.com/en-us/windows/uwp/data-binding/function-bindings.
This works fine as long as the parameter has a value. But if the parameter is null, the function is not called and the binding uses FallbackValue instead (if it is defined).
<TextBlock Text="{x:Bind local:MainViewModel.FormatWidget(ViewModel.SelectedItem), Mode=OneWay, FallbackValue=MyFallbackValue}" />
Interestingly, if the initial value is null, x:Bind does call the function with the null parameter, but on any subsequent changes when the parameter becomes null, the function is not called. It is for this one reason that I would call this a bug rather than a feature request. Surely this is not the intended behavior.
Please fix x:Bind to accept null parameters.
Original Comments
Visual Studio Feedback System on 3/24/2020, 10:27 PM:
We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.
Original Solutions
(no solutions)
+1 to this, there seem to be no proper way to have fine-tuned control for null
values with x:Bind
to function.
And the behavior itself also seems inconsistent as OP mentioned, with the function being invoked only the first time with just null
as argument, and then further invocations just skipped, with FallbackValue
being used. I think if FallbackValue
is to be supported in this case, it should always be used, even for the initial binding update.
In my case, I was setting up some samples for the MVVM Toolkit library (see https://github.com/windows-toolkit/WindowsCommunityToolkit/issues/3230), and came up with this:
<Run
xmlns:ex="using:Microsoft.Toolkit.Extensions"
Text="{x:Bind ex:TaskExtensions.GetResultOrDefault(ViewModel.DownloadTextCommand.ExecutionTask), Mode=OneWay}"/>
That DownloadTextCommand
is an IAsyncRelayCommand
instance (from the same library). That ExecutionTask
is a Task<T>
that is never null
. The issue is that the code above just throws a NullReferenceException
, as the x:Bind
code always calls that function that's bound to, no matter the input value. You can see this in the codegen:
The binding is only checking the parent for null
values, but not the leaf property being accessed.
I tried with FallbackValue=''
, but that didn't solve the issue - still got a NRE on initialization.
Any thoughts on this? 🤔 Thanks!
Thanks for filing this bug. We will look at fixing this post WinUI 3.0.
1+
Also Related to #1904, I think (may be same root cause?)
Just hit this again and took a few minutes and digging back into the debugger to realize it just wasn't working as expected. This seems like a pretty weird case. Would be nice to get a fix for both UWP and WinUI 3.
Digging into the generated x:Bind code, I can see during initialization it calls a different method that has an aggregate of function calls, here the null check is on something else. However, when the property change gets called, there's a different null check in a different place which causes it not to cascade down to the function call.
It's pretty easy to spot this difference when following up the tree from the generated function wrapper just a couple of levels.
1+
this is BUG. MS Team should take it high priority
@bpulliam
- Is there still a XAML compiler team?
- Can we expect XAML issues like this to ever be fixed?
- If not, then the x:Bind function docs should state that they can't handle null values, requiring that either FallbackValue be used where possible, or a Converter be used instead.
I am trying to bind multiple variables that can be null in WinUI3, but this is not possible due to the lack of IMultiValueConverter and this bug.
Exactly, IMultiValueConverter
died for us to have functions, but they don't work with null
at all.
Bumping as this is still a serious issue in WinU 3 that makes function bindings significantly less viable as a replacement for Converters
Same problem here. Would really like this to work. Calling this.Bindings.Update on the page code behind seems to force the OneWay binding to the function to work with null argument, but really shouldn't need this workaround.