unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.61k stars 694 forks source link

Data binding of ItemsControl oddities #4597

Open mterwoord opened 3 years ago

mterwoord commented 3 years ago

Current behavior

When having an ItemsControl, its items are showing weird databinding behavior, in that they first get the correct datacontext , then the parent context, then the correct context again.

Expected behavior

Items should be created, then the datacontext should be set.

How to reproduce it (as minimally and precisely as possible)

See https://github.com/mterwoord/uno-switching-property-value for a sample project, including description.

Environment

Nuget Package:

Nuget Package Version(s): Tested on 3.2 and 3.3

Affected platform(s):

IDE:

Relevant plugins:

davidjohnoliver commented 3 years ago

@mterwoord I've taken a look and this is a bug coming from ContentPresenter, which is used as container for items by ItemsControl. (I'll put more technical details below if you're interested.)

We'll try to adjust this in Uno, since obviously it's not adequately aligned with UWP, but for now an easy workaround is to use a slightly-customized ItemsControl implementation which uses a ContentControl as item container:

namespace TestUnoApp
{
    public partial class MyItemsControl : ItemsControl
    {
        protected override DependencyObject GetContainerForItemOverride() => new ContentControl();
    }
}

With this, you shouldn't get multiple DataContext changes.

davidjohnoliver commented 3 years ago

Note for contributors:

This is coming from the ContentPresenter.ResetDataContextOnFirstLoad() method: https://github.com/unoplatform/uno/blob/add6a74d911fe35a05481fcc8a68140f1764ead0/src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs#L783

This is meant to be replicating the behaviour of UWP, but obviously it's not giving expected results in cases such as this one.