maui icon indicating copy to clipboard operation
maui copied to clipboard

XamlC resolves x:DataType incorrectly

Open mattleibow opened this issue 3 years ago • 11 comments

Description

This is partly a collection of issues and partly a more specific issue. Not sure if this is 100% a bug in all cases either.

XamlC uses the x:DataType="<type-name>" on <DataTemplate> to generate type-specific bindings, however, somce times the scope is incorrect or if the XAML is wrong but happens to match there is no exception and just fails silently.

In debug you can also get these errors using <_MauiForceXamlCForDebug>true</_MauiForceXamlCForDebug> but still no warnings or exceptions anywhere.

Steps to Reproduce

  1. Clone https://github.com/mattleibow/maui-bug-repros/tree/repro-xamlc-datatype
  2. Run
  3. Observe that not all the collection views have items in them

Link to public reproduction project repository

https://github.com/mattleibow/maui-bug-repros/blob/repro-xamlc-datatype/MauiApp1/MainPage.xaml

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS, Android, Windows, macOS, Other (Tizen, Linux, etc. not supported by Microsoft directly)

Affected platform versions

All versions

Did you find any workaround?

Make sure the x:DataType is specified correctly, and on every level of templates.

Relevant log output

No response

mattleibow avatar Dec 08 '22 11:12 mattleibow

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Dec 08 '22 11:12 ghost

@StephaneDelcroix thoughts?

mattleibow avatar Dec 08 '22 11:12 mattleibow

This may have a simpler repro case: https://github.com/dotnet/maui/issues/13764

mattleibow avatar Mar 08 '23 19:03 mattleibow

Can you give some love (priority) to this issue (I created a duplicated one yesterday the one @mattleibow mentioned) ?

From what I see Compiled bindings don't actually work as compiled bindings in MAUI and this issue is 3 months old

Thanks

danardelean avatar Mar 09 '23 09:03 danardelean

Bump

Syed-RI avatar Mar 18 '23 10:03 Syed-RI

Bump

Syed-RI avatar Apr 27 '23 08:04 Syed-RI

Bump

danardelean avatar Jul 03 '23 13:07 danardelean

Trying to keep the issue alive :)

danardelean avatar Jul 19 '23 12:07 danardelean

Verified this issue with Visual Studio Enterprise 17.7.0 Preview 3.0(net8). Can repro on Windows platform with sample Project. https://github.com/mattleibow/maui-bug-repros/tree/repro-xamlc-datatype image

homeyf avatar Jul 21 '23 07:07 homeyf

@StephaneDelcroix Can I add this one to your short list?

samhouts avatar Sep 13 '23 00:09 samhouts

I can reproduce the issue with a Button in a CollectionView DataTemplate that binds to a Command on the page's BindingContext and passes the data binding element {Binding .} to it as a parameter

my comment and repro from https://github.com/dotnet/maui/issues/13754#issuecomment-1707051056

still a critical issue with version 8.0.0-preview.7.8842 which completely breaks CollectionView (haven't tested with other collection controls) on Windows. I have the usecase of a Button inside a CollectionView that has a Command binding to the ViewModel and passes the current Item (MyItem class) as a CommandParameter.

Executing this command fails of course because the Type of the CommandParameter is ViewModel instead of MyItem Error Message: Parameter "parameter" (object) cannot be of type MauiApp1.MainViewModel, as the command type requires an argument of type MauiApp1.MyItem. (Parameter 'parameter')

StackTrace:

   at CommunityToolkit.Mvvm.Input.RelayCommand`1.ThrowArgumentExceptionForInvalidCommandArgument(Object parameter)
   at CommunityToolkit.Mvvm.Input.RelayCommand`1.Execute(Object parameter)
   at Microsoft.Maui.Controls.ButtonElement.ElementClicked(VisualElement visualElement, IButtonElement ButtonElementManager)
   at Microsoft.Maui.Controls.Button.SendClicked()
   at Microsoft.Maui.Controls.Button.Microsoft.Maui.IButton.Clicked()
   at Microsoft.Maui.Handlers.ButtonHandler.OnClick(Object sender, RoutedEventArgs e)
   at WinRT._EventSource_global__Microsoft_UI_Xaml_RoutedEventHandler.EventState.<GetEventInvoke>b__1_0(Object sender, RoutedEventArgs e)
   at ABI.Microsoft.UI.Xaml.RoutedEventHandler.Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e)
--- End of stack trace from previous location ---
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|20_0(Int32 hr)
   at WinRT.ExceptionHelpers.ThrowExceptionForHR(Int32 hr)
   at ABI.Microsoft.UI.Xaml.Controls.IControlOverridesMethods.OnPointerReleased(IObjectReference _obj, PointerRoutedEventArgs e)
   at Microsoft.UI.Xaml.Controls.Control.OnPointerReleased(PointerRoutedEventArgs e)
   at Microsoft.UI.Xaml.Controls.Control.Microsoft.UI.Xaml.Controls.IControlOverrides.OnPointerReleased(PointerRoutedEventArgs e)
   at ABI.Microsoft.UI.Xaml.Controls.IControlOverrides.Do_Abi_OnPointerReleased_3(IntPtr thisPtr, IntPtr e)

And of course the output log is filled with Binding Diagnostic Errors:

Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'ClickCommand' property not found on 'MauiApp1.MainViewModel', target property: 'Microsoft.Maui.Controls.Button.Command'
Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'Name' property not found on 'MauiApp1.MainViewModel', target property: 'Microsoft.Maui.Controls.Label.Text'
Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'Description' property not found on 'MauiApp1.MainViewModel', target property: 'Microsoft.Maui.Controls.Label.Text'

image

My Repro:

MauiApp1.zip

nor0x avatar Sep 13 '23 11:09 nor0x

I wrote a test for 13764 and it looks like this no longer happens (main branch). The observer behavior is as follow

  • on Debug, x:DataType is ignored, and binding are resolved if possible using reflection
  • on Release, bindings with the wrong x:DataType silently fail

making the page crash on mismatching DataType is NOT an option, as the binding context could change multiple times when parenting the element until the 'right' context is set

what are the expectation ? sending a binding diagnostic warning on Debug ?

StephaneDelcroix avatar Apr 02 '24 13:04 StephaneDelcroix

I suppose I lumped them all in together because I suppose I expected an exception. But maybe these are 3 separate issues and one is "just add a message".

Probably this one is more we need to add some logging or maybe a way to detect this. The generated code is using the type in the XAML, and thus it does not work. Maybe a detection can be added or logs:

<!--
    This results in an incorrect UI because the DataType on the
    DataTemplate is the wrong one.
    The generated TypedBinding is using the "incorrect" types:
         TypedBinding<SubItem, string>
-->
<Label Text="Incorrect binding, an incorrect DataType:" />
<CollectionView ItemsSource="{Binding Items}" HeightRequest="100">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:SubItem">
            <Label Text="{Binding Name}" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

This one feels more actionable somehow because of a missing DataType, the inner layer is using the outer type. In this case, the ItemsSource is always (maybe) going to change the binding context of the items. Should there be a way to say that we are using a DataType on an outer layer, so "reset" the type for the inner CV?

<!--
    This results in an incorrect UI because there is no DataType on the
    DataTemplate and XamlC falls back to the DataType on the one above.
    The generated TypedBinding is using the incorrect types:
         TypedBinding<CollectionItem, string>
-->
<Label Text="Incorrect nested binding, parent DataType:" />
<CollectionView ItemsSource="{Binding Items}" HeightRequest="100">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:CollectionItem">
            <CollectionView ItemsSource="{Binding SubItems}" HeightRequest="100">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Label Text="{Binding Name}" />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

This is probably a user error, but I have seen it happen a lot in samples. The DataType attribute is on the ItemTemplate property... shomehow... so should this be a XAMLC error as there is no way to do this in reality?

<!--
    This results in an incorrect UI because the DataType is not on the 
    DataTemplate so is ignored.
    The generated TypedBinding is using the incorrect types:
         TypedBinding<CollectionItem, string>
-->
<Label Text="Incorrect nested binding, parent DataType:" />
<CollectionView ItemsSource="{Binding Items}" HeightRequest="100">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:CollectionItem">
            <CollectionView ItemsSource="{Binding SubItems}" HeightRequest="100">
                <CollectionView.ItemTemplate x:DataType="local:SubItem">
                    <DataTemplate>
                        <Label Text="{Binding Name}" />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

mattleibow avatar Apr 02 '24 13:04 mattleibow

@mattleibow I created this PR that will warn if there's a Binding that inherits the x:DataType from outside of its DataTemplate scope: https://github.com/dotnet/maui/pull/22803 Would that resolve this issue?

simonrozsival avatar Jun 20 '24 08:06 simonrozsival