AvaloniaMauiHybrid icon indicating copy to clipboard operation
AvaloniaMauiHybrid copied to clipboard

Using bindings for MAUI controls causes view to not be rendered at all

Open gentledepp opened this issue 1 year ago • 10 comments

Hello... me again.

I am really sorry for bothering you guys, but I keep bumping into stuff.

I am currently trying to "copy" the implementation of the sample of ZXing Maui Barcode Reader

This is the view I try to move to Avalonia: https://github.com/Redth/ZXing.Net.Maui/blob/main/BigIslandBarcode/MainPage.xaml

I managed to get it to work and actually get rendered.

1st attempt - keep everything in Maui

This worked on my android emulator (API 30) but on my physical device (Huawei p30 pro) the UI remains empty

2nd attempt - use avalonia, and only wrap the barcodescanner in host

Now, it renders the barcode scanner view, but as soon as I add any binding to those controls (even for bool values), the UI is not rendered anymore - the screen stays brown which is the background color of the Avalonia MainView image

Am I missing something here?

Additionally, the rendering seems to not work correctly either: The camera view should be shown inside the empty space here image

But is actually rendered on top/covering everything else on the emulator: image

It works though on my device... :-|

gentledepp avatar May 06 '24 13:05 gentledepp

I don't know why it stops rendering the native control once binding is added, but I can say for sure that bindings aren't supported here. It's actually pretty similar to https://github.com/AvaloniaUI/AvaloniaMauiHybrid/issues/20 issue.

In Avalonia XAML, bindings and xName works well, since all the elements are AvaloniaObjects. The same goes with MAUI, it all works while all elements are known to MAUI framework.

But when we mix different frameworks, it gets more complicated. You can't apply Avalonia.Binding to Maui.Control, since it doesn't inherit AvaloniaObject.

Known workaround is to create a separated MAUI Page (or ContentView) and setup MAUI Bindings there. And in Avalonia XAML file only include this Page, without any extra bindings. This way, you will have one MAUI XAML file with MAUI bindings, and another Avalonia XAML file that has first one as a content.

maxkatz6 avatar May 07 '24 07:05 maxkatz6

And to be clear, while it's technically possible to add x:Name support for MAUI elements, I don't think we can support bindings on MAUI controls, without making adding MAUI as a first-class support to our XAML compiler.

maxkatz6 avatar May 07 '24 07:05 maxkatz6

Ideally, ZXing.Net.Maui should be re-ported to Avalonia using NativeControlHost, avoiding any other frameworks in between. Hard to tell, how difficult it would be though. Technically, only camera view (a native control) needs to be wrapped into a NativeControlHost.

maxkatz6 avatar May 07 '24 07:05 maxkatz6

yeah.. I aggree...

Regarding the preview overlapping everything else: This seems to be a zxing.maui issue: If I run their demo project and try to put the camera preview into the middle row, it still overlaps. https://github.com/Redth/ZXing.Net.Maui/issues/4

The difference is, that AvaloniaMauiHybrid always renders all MAUI controls on top of everything else. So I cannot render any avalonia controls on top of MAUI, correct? Or is that a bug?

gentledepp avatar May 07 '24 08:05 gentledepp

On overlapping issue - the same would be with Avalonia-only port. Since native controls would be rendered on top of any avalonia content.

So I cannot render any avalonia controls on top of MAUI, correct?

So, yes. That's correct. We have plans to support Popup (and Popup-related controls, like tooltip or flyout) to work on a separated layer though. It's already done on desktop (where it often is a separated window).

maxkatz6 avatar May 07 '24 09:05 maxkatz6

Ok... makes sense. Now, I updated the sample, so that the MAUI controls are in a separate MAUI View. They share the same BindingContext/DataContext (QRCodeViewModel) theough.

But: Again the bindings do not have any effect on the MAUI controls. Any thoughts?

gentledepp avatar May 07 '24 11:05 gentledepp

They share the same BindingContext/DataContext (QRCodeViewModel) theough.

Looks like DataContext isn't passed automatically. But it's something that should be handled by this library.

A workaround to add (in QRCodeView.axaml.cs file):

protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
    base.OnPropertyChanged(change);

    if (change.Property == DataContextProperty)
    {
        ProgressBarHost.Content!.BindingContext = change.NewValue;
        BarcodeViewHost.Content!.BindingContext = change.NewValue;
    }
}

I also added BarcodeViewHost x:Name on the BarcodeView control host.

maxkatz6 avatar May 08 '24 14:05 maxkatz6

Apologies... I could have come to that conclusion myself... 😕 Thank you so much for all your valuable responses!

gentledepp avatar May 08 '24 16:05 gentledepp

Sorry - me again. Now I tried out using ReactiveUI within MAUI controls.

For this, I started from the functioning prototype, where the MAUI UI parts are split out into their own views, so the MAUI bindings will work. Everything works fine.

Now, i changed the ContentViews to become ReactiveContentView<>s and wanted to check if WhenActivated() was ever called. It turns out, that, again, the UI simply isn't rendered anymore.

You can check out the branch here: https://github.com/gentledepp/POC_AvaloniaMauiApp01/tree/poc/settingmauipropsincodebehind

So is this now a bug or again some known shortcoming?

gentledepp avatar May 15 '24 13:05 gentledepp

Additionally this POC has two demo viewmodels: PicturesViewModel and QRCodeViewModel. To "navigate" between them, the MainViewModel contains a ContentControl and a command that just swaps the CurrentViewModel image

Interestingly, navigating from the QRCodeView to the PicturesView causes the PicturesView to (again) not be rendered at all:

truncation

Note: This also "works" when

  • starting out with the QRCodeViewModel
  • or re-using the viewmodel instances

gentledepp avatar May 15 '24 14:05 gentledepp