CommunityToolkit / WindowsCommunityToolkit

The Windows Community Toolkit is a collection of helpers, extensions, and custom controls. It simplifies and demonstrates common developer tasks building .NET apps with UWP and the Windows App SDK / WinUI 3 for Windows 10 and Windows 11. The toolkit is part of the .NET Foundation.
https://docs.microsoft.com/windows/communitytoolkit/
Other
5.88k stars 1.38k forks source link

TokenizingTextBox Binding Layout Conflict for ItemsSource #3712

Open hawkerm opened 3 years ago

hawkerm commented 3 years ago

Describe the bug

Can't set binding to the TokenizingTextBox ItemsSource in XAML directly. This seems to work in the sample app, but it's doing it from code-behind after the control has been loaded.

Steps to Reproduce

Have an ObservableCollection<string> of items in my code. Then trying to bind it directly to the TokenizingTextBox:

<controls:TokenizingTextBox ItemsSource="{x:Bind MyItems, Mode=TwoWay}"/>

(Doesn't matter if OneWay or TwoWay.)

Fails on application launch.

Expected behavior

Able to bind to ItemsSource directly in XAML. It should pre-populate any items from the backing collection, and then any edits from the user should be seen in my backing collection as well.

Environment

NuGet Package(s): build746 (latest main)

Package Version(s): 

Windows 10 Build Number:
- [ ] Fall Creators Update (16299)
- [ ] April 2018 Update (17134)
- [ ] October 2018 Update (17763)
- [ ] May 2019 Update (18362)
- [x] May 2020 Update (19041)
- [ ] Insider Build (build number: )

App min and target version:
- [ ] Fall Creators Update (16299)
- [ ] April 2018 Update (17134)
- [ ] October 2018 Update (17763)
- [ ] May 2019 Update (18362)
- [x] May 2020 Update (19041)
- [ ] Insider Build (xxxxx)

Device form factor:
- [x] Desktop
- [ ] Xbox
- [ ] Surface Hub
- [ ] IoT

Visual Studio 
- [ ] 2017 (version: )
- [x] 2019 (version: ) 
- [ ] 2019 Preview (version: )

Additional context

Child collection must not be modified during measure or arrange.
   at Windows.UI.Xaml.Controls.ItemsControl.put_ItemsSource(Object value)
   at Project.Views.MainPage.XamlBindingSetters.Set_Windows_UI_Xaml_Controls_ItemsControl_ItemsSource(ItemsControl obj, Object value, String targetNullValue)
   at Project.Views.MainPage.MainPage_obj5_Bindings.Update_MyItems(ObservableCollection`1 obj, Int32 phase)
   at Project.Views.MainPage.MainPage_obj5_Bin

I am swapping out my collection object depending on if I have values, so if I remove all initializations of my backing ObservableCollection then the app loads, but the control is disabled. Though sometimes I get:

System.Runtime.InteropServices.COMException: Error HRESULT E_FAIL has been returned from a call to a COM component.
   at Windows.UI.Xaml.FrameworkElement.MeasureOverride(Size availableSize)
ghost commented 3 years ago

Hello hawkerm, thank you for opening an issue with us!

I have automatically added a "needs triage" label to help get things started. Our team will analyze and investigate the issue, and escalate it to the relevant team if possible. Other community members may also look into the issue and provide feedback 🙌

Rosuavio commented 3 years ago

I am trying to reproduce the bug and I it seems to be working fine. I made a project with MainPage.xaml

<Page
    x:Class="Periscope.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="using:Periscope"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <controls:TokenizingTextBox ItemsSource="{x:Bind MyItems}"/>
</Page>

MainPage.xmal.cs

namespace Periscope
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<string> MyItems { get; }

        public MainPage()
        {
            MyItems = new ObservableCollection<string>()
            {
                "First",
                "Second",
                "Third"
            };
            this.InitializeComponent();
        }
    }
}

I seems to work fine.

image

Rosuavio commented 3 years ago

I cant seem to get this bug to occur. I am not sure its still an issue.

michael-hawker commented 3 years ago

Thanks @RosarioPulella, I'll move this to 7.1 then and see if I can check for differences in whatever setup I had.