dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.22k stars 1.75k forks source link

[DataTemplate/CollectionView] : Inconsistent behavior btw Release/Debug config with Xaml -> Bindings not working when x:DataType is not specified in Release mode #20002

Open bebenlebricolo opened 9 months ago

bebenlebricolo commented 9 months ago

Description

[Appears on Android, physical and emulator devices]

DataBinding don't seem to fully work in <DataTemplate></DataTemplate> if x:DataType="customenamespace:MyDataModel" is not explicitely specified as DataTemplate property. More specifically, events are well propagated and properties properly propagate the updates to the code-behind.

However, it seems DataTemplate is missing the Type information in release mode (which is conveyed fine in Debug builds). Hence, the controls within the DataTemplate tag are bound, but they can't access the data they need to display. This is true for POD and for functions (I had app crashes when clicking on an item of the CollectionView in release mode without the DataType property, probably because the event function couldn't be found).

In-situ app demonstration :

With the DataType property : image

Without the DataType property : image

Here is the code snippet which is responsible for this :

<CollectionView.ItemTemplate>
     <DataTemplate>
 <!-- <DataTemplate x:DataType="datamodels:CompactHopModel">   This solves the issue    --> 
          <Grid>
              <controls:HopCardView BindingContext="{Binding .}" />
          </Grid>
    </DataTemplate>
</CollectionView.ItemTemplate>

As you can see, all properties (Labels here) are missing from the render. Furthermore, as said, when I click on a card, it normally navigates (with the Shell) to a new page where we can find details about the selected item. This relies on a RelayCommand which is bound to the ViewModel. In Debug mode, this works fine. In Release mode with the DataType property, it also works fine. In Release mode without the DataType property, it crashes.

Note : this issue was described in StackOverflow and in another issue that is around 1 year old now

Steps to Reproduce

  1. Clone DotnetMaui-DataTemplateBug
  2. Open the solution and follow the Readme.md instructions.
  3. Cheers ! :beers:

Link to public reproduction project repository

https://github.com/bebenlebricolo/DotnetMaui-DataTemplateBug

Version with bug

8.0.6

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Api levels 30 to 34 at least (Android 11 and above)

Did you find any workaround?

Explicitely specify x:DataType information as DataTemplate property

Relevant log output

No response

divyesh008 commented 9 months ago

Yes, I have face the same. +1

D-Parkinson1 commented 8 months ago

Also seeing this with a slight variation. Even if there is a dataType specified it can still not show the label if the dataType is incorrect (which is user error, but still works for debug, and not release).

For example,

<CollectionView ItemsSource="{Binding MenuItems}" IsGrouped="True">
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate x:DataType="models:Item">
                <Label TextColor="Black" BackgroundColor="White" Text="{Binding Name}" />
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Border>
                <Label Text="{Binding .}" TextColor="White" BackgroundColor="BlueViolet"/>
            </Border>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

View Model and Other classes:

public partial class MainPageViewModel : ObservableObject
{
    [ObservableProperty]
    private ObservableCollection<MenuCategory> menuItems = [];

    public MainPageViewModel() {
        menuItems =
        [
           new("Group 1", [new("One", "1"), new("Two", "2"), new("Three", "3")]),
           new("Group 2", [new("1", "11"), new("2", "22"), new("3", "33")])
        ];
    }
}

public record Item(string Name, string Other);

public class MenuCategory(string name, IReadOnlyCollection<Item> items) : ObservableCollection<Item>(items)
{
    public string Name { get; private set; } = name;
}

In this case, both Item and MenuCategory have a property name and so compile fine, no intellisense errors. But the header template is really of type MenuCategory but we specified Item, so even though Item compiles and builds fine, the labels are blank in release, but show fine in debug mode.

kevinxufei commented 7 months ago

Can repro this issue at Android platform on the latest 17.10.0 Preview 2.0(8.0.14/8.0.3) with sample project.

StephaneDelcroix commented 6 months ago

@D-Parkinson1 issue (and other mismatching behaviour between debug/release) fixed by #22056