-
Notifications
You must be signed in to change notification settings - Fork 698
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
TreeView with DataTemplateSelector not reliably using selected DataTemplate #2121
Comments
@Shad0wlife I really appreciate the standalone repro. From what you are saying, this sounds like a bit of timing is involved to get the repro. I'm having trouble repro'ing the crash or the issue with the data template selector not picking the correct template unfortunately. Can you share a crash dump ? |
I have some very bad news... (Updated my Repository with the ListView stuff as well) |
@Shad0wlife If this is an issue with ListView, the fix will have to wait for WinUI3 to fix it unfortunately since ListView is not part of this repo. Regarding the crash dumps, you can upload to watson, file a feedback hub item and share the feedback link here. |
I think I backtracked it to the Virtualization, effectively disabling it (by wrapping the ListView in a Scrollviewer) seems to completely block the issue from appearing. I found this documentation for Virtualization: I'll investigate further whether this approach (even if very inefficient) can be used as a workaround for now. EDIT: |
I found a temporary workaround for my use case: For now this issue is somewhat solved to me, but i'll still try to verify the issue on a newer Win10 build. |
@Shad0wlife disabling virtualization is a reasonable workaround if you have limited number of items. How many items do you expect the list to have? If there are lots of items, layout can get very slow and your memory consumption will also go up quite a bit. Try out your worst case scenario before you go down that path. Also, can you check if you hit the issue with x:Bind and Binding or just x:Bind ? |
I don't see any Binding or x:Bind that would be relevant until after the bug manifested. I think there really won't be more than maybe 200 to 250 items in there, but depending on the level of nesting in the TreeView, there might be more. The full implementation is backed by a Database and the user can add new elements by buttons or context menu. So depending on what the users do, it might grow differently. I'll ask around, but thanks for the heads up! |
Terminal's running into this too. I suppose we could disable virtualization, but are there any other workarounds? |
Terminal has a DataTemplateSelector and 3 DataTemplates. Each DataTemplate contains a One of the We must either:
From my comment on microsoft/terminal#9487:
|
There seems to be a bug in WinUI (see microsoft/microsoft-ui-xaml#2121) that results in heterogeneous `ModernCollectionBasePanel` configured with `DataTemplateSelector` and virtualization enabled to recycle a container even if its `ContentTemplate` is wrong. I considered few options of handling this: * Disabling virtualization (by replacing item container template with some non-virtualizing panel (e.g., `StackPanel`, `VirtualizingStackPanel` with `VirtualizationMode`=`Standard`) * Replacing `DataTemplateSelector` approach with `ChoosingItemContainer` event handling approach, which allows you to manage the item container (`ListViewItem`) allocation process. I have chosen the last one, as it should limit the amount of allocations, and might allow optimizations in the future. The solution introduces: * A container for `ListViewItem`s in the form of a map of sets: * The key of this map is a data template (e.g., `TabItemDataTemplate`) * The value in the set is the container * `ChoosingItemContainer` event handler that looks for available item in the container or creates a new one * `ContainerContentChanging` event handler that returns the recycled item to the container Closes #9288
There seems to be a bug in WinUI (see microsoft/microsoft-ui-xaml#2121) that results in heterogeneous `ModernCollectionBasePanel` configured with `DataTemplateSelector` and virtualization enabled to recycle a container even if its `ContentTemplate` is wrong. I considered few options of handling this: * Disabling virtualization (by replacing item container template with some non-virtualizing panel (e.g., `StackPanel`, `VirtualizingStackPanel` with `VirtualizationMode`=`Standard`) * Replacing `DataTemplateSelector` approach with `ChoosingItemContainer` event handling approach, which allows you to manage the item container (`ListViewItem`) allocation process. I have chosen the last one, as it should limit the amount of allocations, and might allow optimizations in the future. The solution introduces: * A container for `ListViewItem`s in the form of a map of sets: * The key of this map is a data template (e.g., `TabItemDataTemplate`) * The value in the set is the container * `ChoosingItemContainer` event handler that looks for available item in the container or creates a new one * `ContainerContentChanging` event handler that returns the recycled item to the container Closes #9288 (cherry picked from commit e02d9a4)
Env: Win10, VS2019 + C#9.0 or VS2022preview + C#10.0 I encountered the same InvalidCastException problem when using a TreeView combined with a The exception is thrown out from XAML generated code e.g. MainPage.g.cs, and it involves COM code so conditional breakpoint is not working, and the exeption occurs only when there's a lot of items in the tree view, so effectively I have no way to break the running code just before exception occurs and run watch code to check stack data. Eventually I wrote a MSBuild plugin to configurably modify generated MainPage.g.cs before it is compiled and inserted some condition check and debug output code, and I found some truth and had some guess on root cause of the exception. Conclusion:The exception is caused by virtualization mechanism, which recycles and reuses binding objects corresponding to off-screen(may be far from screen visible region) items, and rebind new data objects to them. If data type is provided by The solutions:
Condition that will trigger the bug: meet either of 2 conditions:
Either 1 or 2, there shall be items corresponding to different data types involved. An example:I wrote a explorer-like program that shows file tree using TreeView. There are 2 CommentI wish this problem be fixed by developers, hopefully using solution 4. because I see no reason data types of different Some key code://------------ MainPage.xaml -----------------
//------------ MainPage.g.cs ------------------
|
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
Still exists! |
Any news on that ? Thanks |
Surprise surprise! we ran into an old friend: * #9288 * #9487 * microsoft/microsoft-ui-xaml#2121 so uh, this is ded.
Describe the bug
I have a tree view. I want to fill it with 2 types of data - one that can have children and one that can not. The template is selected with an DataTemplateSelector which checks the node.Content type for the selection.
The data is given in 2 lists that get iterated one after another. The root nodes are given based upon the selection of a combobox - a new selection clears the treeview and repopulates it.
After an Item is added, the task is delayed for a few milliseconds to avoid lagging gui because the layouting can't keep up when adding a hundred elements to the treeview. When starting to add the second type, the ItemTemplateSelector selects the correct template (I check that with Debug logging), but the TreeView still uses the template of the first item type, causing a crash with anInvalidCastException when attempting to cast the node.Content.
This does not happen when I let the TreeView fully populate, but only when I cancel it by clearing the RootNodes and repopulate them with new data.
Steps to reproduce the bug
Expected behavior
The selected template of the DataTemplateSelector is respected for every node added.
Screenshots
The Error with log showing that the correct template was given by the selector:
The visual representation with non-crashing templates:
It can be seen that the nodes get the corresponding HasUnrealizedChildren value, but the Template used is the wrong one.
Version Info
Package version: 2.4.0-prerelease.200203002
OS Version: 1809
Project Target: 1903 (required by package)
Project Minimum: 1809
NuGet package version:
Microsoft.UI.Xaml
Package version: 2.4.0-prerelease.200203002
Additional context
This might also be an issue with how I implemented things, so If you see the issue somewhere in my code please tell me!
If you want to see the effect yourself without crashing, you can enable the debugging templates in MainPage.xaml instead of the full Templates. These templates are visually distinct but won't crash due to casts.
EDIT: I kept in the Attributes for my Database code that the full application uses in case they impact the result due to possible extra load or so. That said: the linked repo is obviously a sample app created from a larger project cut down to a standalone program to show the issue. I just wanted to keep all code affecting any of the process from data to layout as intact as possible.
The text was updated successfully, but these errors were encountered: