Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListView sets Cell's BindingContext to self, causing multiple warnings and/or InvalidCastExceptions #13754

Closed
DanTravison opened this issue Mar 8, 2023 · 10 comments
Assignees
Labels
area-controls-listview ListView and TableView platform/windows 🪟 s/triaged Issue has been reviewed t/bug Something isn't working

Comments

@DanTravison
Copy link

Description

When ListView has an ItemsSource and ItemTemplate defined, the ViewCell.BindingContext for the ItemTemplate is initially set the BindingContext of the ListView itself instead of the associated ItemsSource value.

The problem occurs in Maui when the Element.SetParent is called on the Cell. This calls BindableObject.SetInheritedBindingContext which ends up setting the ListView's BindingContext on the ViewCell instead of the intended value from the ItemsSource. This propogates down the contained View's ItemsSource which, in the StackLayout case, expects an IEnumerable. Since the ListView's BindingContext is not an IEnumerable, an InvalidCastException(Object must implement IConvertible) is raised by Convert.ChangeType. If the ListView's BindingContext does implement IEnumerable, a flood of BindingDiagnostics: Warnings occur for each Cell also due to the incorrect value.

I see this sequence occur twice for each cell as the ListView is populated causing a user noticeable delay in displaying the associated page.

With the simpler case of an ItemTemplate that does not bind to an IEnumerable, numerous warnings are output as each View binding is resolved. For a large list, this is prohibitive.

The view eventually populates after multiple binding failures. In the InvalidCastException case, at least 2 failures per ItemsSource value occur before success. I have not determined the number of failures for the 'simpler' case.

I can repro this on Windows but do not see it on iOS, macOS, or Android.

Steps to Reproduce

See the referenced sample project.

Link to public reproduction project repository

https://github.com/DanTravison/ListViewBinding

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

10.0.19041.0

Did you find any workaround?

No.
The only way I've found to avoid the issue is to not use ListView. However, I have not found a viable alternative that provides item-level scrolling.

Relevant log output

No response

@DanTravison DanTravison added the t/bug Something isn't working label Mar 8, 2023
@jsuarezruiz jsuarezruiz added the area-controls-listview ListView and TableView label Mar 8, 2023
@daltzctr
Copy link
Contributor

This makes ListView completely broken on WinUI, as you are not able to present views based on the binding

@homeyf homeyf added the s/triaged Issue has been reviewed label Jul 18, 2023
@homeyf
Copy link

homeyf commented Jul 18, 2023

Verified this issue with Visual Studio Enterprise 17.7.0 Preview 3.0(net8). Not repro on windows platform with sample project.
https://github.com/DanTravison/ListViewBinding
image

@homeyf homeyf added the s/try-latest-version Please try to reproduce the potential issue on the latest public version label Jul 18, 2023
@ghost
Copy link

ghost commented Jul 18, 2023

Hi @DanTravison. We have added the "s/try-latest-version" label to this issue, which indicates that we'd like you to try and reproduce this issue on the latest available public version. This can happen because we think that this issue was fixed in a version that has just been released, or the information provided by you indicates that you might be working with an older version.

You can install the latest version by installing the latest Visual Studio (Preview) with the .NET MAUI workload installed. If the issue still persists, please let us know with any additional details and ideally a reproduction project provided through a GitHub repository.

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@daltzctr
Copy link
Contributor

Still occurs in .NET 8 Preview 6

@DanTravison
Copy link
Author

@homeyf I'm curious if you've reviewed the debug output for the sample because I see no change in the behavior.

I installed .Net Maui Preview via Visual Studio installer, changed the project to build for .net 8 and MauiVersion8.0.0-preview.6.8686 and and debug output is flooded with InvalidCastException messages.

A more deterministic repo is to check System.InvalidCastException in the VS Exceptions Settings window.

You'll see an InvalidCastException with 'Object must implement IConvertible.' for each bound object.

If you step up to the caller in the call stack, you'll see BindingExpression.TryConvert attempting to convert ListVIewBinding.ViewModels.ColorsViewModel to IEnumerable when it binds StackView's BindableLayout.ItemsSource property; which expects an IEnumerable.

The actual binding expression is ItemsSource="{Binding Nested.Colors}" which should resolve to ColorsViewModel.Nested.Colors. Eventually, it does but not before first failing to bind the invalid value.

As an aside: If ColorsViewModel implemented IEnumerable, the binding would cause StackLayout to binding to an invalid IEnumerable on the first pass.

Note that the sample has two repros, both defined in mainpage.xaml.

To repro the second, comment out the first Label and ListVIew elements and uncomment the second Label and ListView elements. When you build and run the sample, you will now see two paris of warnings for each bound object. This is also caused by the same problem of binding the parent's BindingContext to each bound object.

The target, defined by ListViewItemTemplate, expects a NamedColor with a Name and Color property but receives a ColorsViewModel.
...
Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'Name' property not found on 'ListViewBinding.ViewModels.ColorsViewModel', target property: 'Microsoft.Maui.Controls.Label.Text'
Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'Color' property not found on 'ListViewBinding.ViewModels.ColorsViewModel', target property: 'Microsoft.Maui.Controls.Shapes.Rectangle.Fill'
...

@ghost ghost removed the s/try-latest-version Please try to reproduce the potential issue on the latest public version label Jul 18, 2023
@DanTravison
Copy link
Author

I've updated the sample to add a .Net 8 and Maui 8.0.0-preview.6.8686 solution and csproj.

@nor0x
Copy link
Contributor

nor0x commented Sep 5, 2023

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

Related Issues:
#8433
#15579
#13754
#11956

EDIT:
related?? #16787

anyone found a workaround yet? this used to be fine with .NET 7!

@PureWeen PureWeen added the i/regression This issue described a confirmed regression on a currently supported version label Sep 8, 2023
@PureWeen PureWeen added this to the .NET 8 GA milestone Sep 8, 2023
@PureWeen PureWeen self-assigned this Sep 11, 2023
@samhouts samhouts removed the i/regression This issue described a confirmed regression on a currently supported version label Sep 12, 2023
@samhouts
Copy link
Member

The ListVIew and CollectionView issues look similar, but they are very different, as far as I can tell. They do not share the same code that was changed in 8.0.0-preview1. The CollectionView issue is a regression in 8.0.0, but this ListView issue presents identically in both 7.0.0 and 8.0.0.

Both are important, although the CollectionView issue takes priority as it is actually preventing the bindings from resolving and thus the application is broken entirely. From my testing, the ListView bindings do resolve, despite the many irritating warnings.

@samhouts
Copy link
Member

Duplicate of #8433

@samhouts samhouts marked this as a duplicate of #8433 Sep 12, 2023
@github-project-automation github-project-automation bot moved this from Todo to Done in MAUI SDK Ongoing Sep 12, 2023
@samhouts
Copy link
Member

If you're using a DataType on your DataTemplate and you find that the items are not showing up at all, you may be hitting this issue instead: #11956

@ghost ghost locked as resolved and limited conversation to collaborators Oct 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-listview ListView and TableView platform/windows 🪟 s/triaged Issue has been reviewed t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants