AvaloniaUI/Avalonia

Null-conditional operators for nested Bindings

Opened this issue · 0 comments

Is your feature request related to a problem? Please describe.

My application uses a "Device" model which represents a physical device that is attached to the PC. The Device model holds all the information that shall be displayed by the UI. For an example a part of the UI shall not be visible while the device is synchronizing:

<StackPanel.IsVisible>
  <MultiBinding Converter="{x:Static BoolConverters.And}">
    <Binding Path="!SelectedDevice.IsSynchronized" />
    <Binding Path="!SelectedDevice.IsSynchronizing" />
  </MultiBinding>
</StackPanel.IsVisible>

The problem is that when no device is connected, "SelectedDevice" will be null causing binding errors even if TargetNullValue or FallbackValue are added.

Also the MultiBinding will not be evaluated, e.g.

<StackPanel.IsVisible>
  <MultiBinding Converter="{x:Static BoolConverters.And}">
    <Binding Path="!SelectedDevice.IsSynchronized" FallbackValue="True" />
    <Binding Path="!SelectedDevice.IsSynchronizing" FallbackValue="True" />
    <Binding Path="!SomeOtherCondition" />
  </MultiBinding>
</StackPanel.IsVisible>

will never be true, regardless of the value of "SomeOtherCondition" as the binding already fails when evaluating "SelectedDevice".

Describe the solution you'd like

An elegant solution has been proposed here: #7857 (reply in thread)

By adding Null-conditional operators to the binding syntax, elements that may be Null could be marked accordingly causing the binding to use the FallbackValue or TargetNullValue instead of failing.

The above example would then look like this:

<StackPanel.IsVisible>
  <MultiBinding Converter="{x:Static BoolConverters.And}">
    <Binding Path="!SelectedDevice?.IsSynchronized" FallbackValue="True" />
    <Binding Path="!SelectedDevice?.IsSynchronizing" FallbackValue="True" />
    <Binding Path="!SomeOtherCondition" />
  </MultiBinding>
</StackPanel.IsVisible>

Describe alternatives you've considered

Currently I work around this by having a "Dummy" device instead of assigning "null" to SelectedDevice when no device is connected.

While this does work in my case, the Null-conditional operators would be a cleaner and more flexible solution.

Additional context

For the original discussion see here: #7857