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

TokenizingTextBox exposes InterspersedObservableCollection instead of ObservableCollection #4248

Open
1 of 20 tasks
michael-hawker opened this issue Sep 14, 2021 · 1 comment
Assignees
Labels
Milestone

Comments

@michael-hawker
Copy link
Member

michael-hawker commented Sep 14, 2021

Describe the bug

The original intent of the TokenizingTextBox was to not expose the internal collection type of InterspersedObservableCollection, and by providing an ObservableCollection to the ItemsSource property, a developer could retrieve only the tokenized elements from the control for their datamodel (or provide them as a pre-population/rehydration on a form).

A developer could then access the Text or raw Items properties to enumerate all partial strings with the Tokens if needed.

However, in the current implementation, we overwrite the ItemsSource value with our InterspersedObservableCollection reference here:

And more importantly here:

This means if you try to setup the scenario as we were in the current Sample app or Graph Sample App (see CommunityToolkit/Graph-Controls#149) binding to the ItemsSource property of the TTB directly, you'd get the internal copy of the InterspersedObservableCollection instead of the inner ObservableCollection of only tokened items.

Steps to Reproduce

  • Can this be reproduced in the Sample App? (Either in a sample as-is or with new XAML pasted in the editor.) If so, please provide custom XAML or steps to reproduce. If not, let us know why it can't be reproduced (e.g. more complex setup, environment, dependencies, etc...)

We can actually observe this in our own sample app (but it was invisible) so we missed it during initial development.

Steps to reproduce the behavior:

  1. Open the TTB page
  2. Go to the Live Visual Tree tools and select the "Current Edit" text
  3. In the Live Visual Tree find the ItemsControl next that's supposed to show the tokenized items.
  4. Note that there'll be a ContentPresenter showing a empty TextBlock, this is a PretokenStingContainer element which shouldn't be part of our collection (only ever exposed on Items and for ToString to get value).

We should expect the ItemsControl to be empty at this time.

We can also further show this corruption by performing a few steps.

  1. Add any two elements and some text:

image

  1. Click on the first token
  2. Type some visible characters, note now that we see the first letter that was set to a PretokenStringContainer within our collection 😲

image

This should not be the case!

Expected behavior

Binding to the ItemsSource even if we don't provide an external collection should only provide the tokenized items. We should only be able to observe the PretokenStringContainer within the Items collection which a developer would check for their own type or call ToString to get the raw values of typed text.

Screenshots

image

Environment

NuGet Package(s): Input

Package Version(s): 7.1.0-rc1

Windows 10 Build Number:

  • Fall Creators Update (16299)
  • April 2018 Update (17134)
  • October 2018 Update (17763)
  • May 2019 Update (18362)
  • 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)
  • May 2020 Update (19041)
  • Insider Build ({build_number})

Device form factor:

  • Desktop
  • Xbox
  • Surface Hub
  • IoT

Visual Studio version:

  • 2017 (15.{minor_version})
  • 2019 (16.{minor_version})
  • 2022 (17.{minor_version})

Additional context

Updated the Graph Sample for now to avoid this issue and show the more practical pattern here: CommunityToolkit/Graph-Controls#160

Should still resolve this issue here.

I believe we did this the way we did initially as since we're inheriting from ListViewBase, we use ItemsPresenter to present the items here:

<ItemsPresenter Padding="{TemplateBinding Padding}"
Margin="{StaticResource TokenizingTextBoxPresenterMargin}"/>

ItemsPresenter grabs the ItemsSource automatically... it's not something we can set. I'm not sure how we override it either, so this is going to need some thought... 🤔

@michael-hawker michael-hawker added bug 🐛 An unexpected issue that highlights incorrect behavior controls 🎛️ labels Sep 14, 2021
@michael-hawker michael-hawker added this to the 7.1 milestone Sep 14, 2021
@michael-hawker michael-hawker self-assigned this Sep 14, 2021
michael-hawker added a commit to michael-hawker/UWPCommunityToolkit that referenced this issue Sep 14, 2021
@michael-hawker
Copy link
Member Author

michael-hawker commented Sep 14, 2021

I've at least started on a fix for the sample itself to work-around the issue here: d528479

I think it's going to be tricky to resolve out-right though as ItemsSource is automatically picked up by the ItemsPresenter, so we need it to be the full collection vs. what we want exposed through the property externally...

I'm not sure what alternatives we may have here to work around this. I did just try to swap to an ItemsControl, but that crashed in the XAML layer somewhere for unknown reasons...

Thinking due to the complexity here (and that it took us a year+ to hit ourselves) that we should move out of 7.1.

michael-hawker added a commit to michael-hawker/UWPCommunityToolkit that referenced this issue Sep 15, 2021
ghost pushed a commit that referenced this issue Sep 16, 2021
## Fixes #4210 and Fixes #4158

Cleans up sample for #4248 (though underlying issue remains to be figured out later).

Fixes a sample and cleans-up a few items we missed in our nuget packages. Just need to validate output from CI, but should be fairly straight-forward.

## PR Type

What kind of change does this PR introduce?

<!-- Please uncomment one or more options below that apply to this PR. -->

<!-- - Bugfix -->
<!-- - Feature -->
<!-- - Code style update (formatting) -->
<!-- - Refactoring (no functional changes, no api changes) -->
<!-- - Build or CI related changes -->
- Documentation content changes
- Sample app changes
<!-- - Other... Please describe: -->

## What is the current behavior?

TTB Sample was binding to the internal collection instead of showing binding to a developer provided collection.

Some new features were missing from the NuGet package info.

## What is the new behavior?

Fixed! 🎉

## PR Checklist

Please check if your PR fulfills the following requirements: <!-- and remove the ones that are not applicable to the current PR -->

- [ ] Tested code with current [supported SDKs](../#supported)
- [ ] New component
  - [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: <!-- docs PR link -->
  - [ ] Added description of major feature to project description for NuGet package (4000 total character limit, so don't push entire description over that)
  - [ ] If control, added to Visual Studio Design project
- [ ] Sample in sample app has been added / updated (for bug fixes / features)
  - [ ] Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/CommunityToolkit/WindowsCommunityToolkit-design-assets)
- [ ] New major technical changes in the toolkit have or will be added to the [Wiki](https://github.com/CommunityToolkit/WindowsCommunityToolkit/wiki) e.g. build changes, source generators, testing infrastructure, sample creation changes, etc...
- [ ] Tests for the changes have been added (for bug fixes / features) (if applicable)
- [ ] Header has been added to all new source files (run _build/UpdateHeaders.bat_)
- [ ] Contains **NO** breaking changes

<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below.
Please note that breaking changes are likely to be rejected within minor release cycles or held until major versions. -->

## Other information

<!-- Please add any other information that might be helpful to reviewers. -->
@michael-hawker michael-hawker modified the milestones: 7.1, 7.2/8.0? Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant