maui
maui copied to clipboard
Children in CollectionView do not inherit BindingContext
Description
I have two issues with BindingContext. First issue is that will not set the correct BindingContext on a ContentView:
<CollectionView.ItemTemplate>
<DataTemplate>
<vm:PersonView BindingContext="{Binding Leader}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
But this will;
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<vm:PersonView BindingContext="{Binding Leader}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
Second issue is that setting a BindingContext from a list is OK. Sample:
<VerticalStackLayout BindingContext="{Binding TheTeams[0]}">
This works fine when running an application. But if compiled binding are used, this will not compile.
Steps to Reproduce
- Create a new MAUI application.
- Add a
ContentViewnamed PersonView with this XAML content:
<VerticalStackLayout>
<Label Text="{Binding PersonName}" />
</VerticalStackLayout>
- Replace the code in MainPage.xaml.cs:
public record Person (string PersonName);
public record Team (string TeamName, Person Leader);
public record Teams (List<Team> TheTeams);
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
Person alice = new Person("Alice");
Team coders = new Team("Coders", alice);
Teams teams = new Teams(new List<Team> { coders });
BindingContext = teams;
}
}
- Replace MainPage.xaml with this:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MauiIssues"
x:Class="MauiIssues.MainPage"
>
<!--Add this to ContentPage to see Issue 2. x:DataType="vm:Teams"-->
<VerticalStackLayout>
<Label Text="Issue 1: " />
<CollectionView ItemsSource="{Binding TheTeams}">
<CollectionView.ItemTemplate>
<DataTemplate>
<!--
Issue 1. This will show nothing. A workaround is to wrap everything in a Grid:
<Grid> <vm:PersonView BindingContext="{Binding Leader}"/> </Grid>
-->
<vm:PersonView BindingContext="{Binding Leader}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!--
Issue 2. These will not compile when x:DataType="vm:Teams" is added to ContentPage.
-->
<Label Text="Issue 2A:" />
<VerticalStackLayout BindingContext="{Binding TheTeams[0]}">
<HorizontalStackLayout BindingContext="{Binding Leader}">
<Label Text="{Binding PersonName}" />
</HorizontalStackLayout>
</VerticalStackLayout>
<Label Text="Issue 2B:" />
<CollectionView ItemsSource="{Binding TheTeams}">
<CollectionView.ItemTemplate>
<DataTemplate>
<VerticalStackLayout>
<HorizontalStackLayout BindingContext="{Binding Leader}">
<Label Text="{Binding PersonName}" />
</HorizontalStackLayout>
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
- Run the application. You will see nothing on issue 1. Wrap the view in Grid and it will work.
- Add
x:DataType="vm:Teams"in theContentPagetag. - The project will no longer compile.
Full sample: https://github.com/pekspro/MauiIssues/tree/9131_BindingContext_cannot_be_changed
Version with bug
6.0.408 (current)
Last version that worked well
Unknown/Other
Affected platforms
Windows, I was not able test on other platforms
Affected platform versions
Windows 10.0.17763.0
Did you find any workaround?
Yes, described in the code.
Relevant log output
No response
Ideally we could just change this line
https://github.com/dotnet/maui/blob/733ba2f93b73e1acacc23d593c5380f188c6b1c9/src/Compatibility/Core/src/Android/CollectionView/TemplatedItemViewHolder.cs#L67
to use
VisualElement.SetInheritedBindingContext(View, itemBindingContext);
But then that causes the BC to flow from the parent which we don't want.
There's a similar case with this if you look at ContentPresenter where it overrides this
internal override void SetChildInheritedBindingContext(Element child, object context)
{
// We never want to use the standard inheritance mechanism, we will get this set by our parent
}
so that the BC doesn't flow from the parent. We don't really have a place to do this with CV but maybe this can be reworked so the BindableObject can get flagged to ignore the parent BC.
I've updated sample application to .NET 7. The same issue remains, and it also an issue on Android.
Verified this on Visual Studio Enterprise 17.7.0 Preview 1.0. Repro on Windows 11 with below Project: 9131.zip
Issue1: Show nothing for Issue1 in application.
Issue2: Run failed with Error XFC0045 "Binding: Property "Leader" not found on "MauiApp11.Teams"." after adding x:DataType="vm:Teams" to ContentPage.