Open SreemonPremkumarMuthukrishnan opened 1 month ago
You can disable text search by setting IsTextSearchEnabled
to false
.
ComboBoxes get unwieldy when there are many items to display. But it gets much better with virtualizing!
Try following in Resources.
<Style TargetType="ComboBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
@xlsupport doesn't help with text search where you need to check each item
@miloush? It does! Also in this case. Check it. instant response on typing & dropdown.
It does help but the reason why it helped is actually not Virtualization itself but the fact that instead of 40k automation peers being created back and forth as you filter it's just those 20-40 for those 20-40 items you see on the screen.
Unrelated and the cause of the issue is elsewhere. If peers weren't created when no client is attached, it wouldn't be an issue in the first place.
@h3xds1nz Filtering? Are you confusing this with his other issue? The one with the DataTable and the awkward filtering?
“Ours is not to wonder why. Ours is just to do or die.”
No, I'm not confusing anything but I've probably chosen insufficient wording; virtualization (ItemContainerGenerator
) basically feeds a filtered out portion of data that it the panel then works with (realized/unrealized blocks).
Point still stands. If you happen to display the popup or click anywhere which causes to display it, aut peers will start being created due to ForceMsaaToUiaBridge
and the whole thing will become insanely laggy even after all the containers would be created.
For the issue displayed on the video, virtualization won't help because the search is done within 40k of those items (as @miloush has outlined, disabling it would help). The search func within the collection is not written in 2024 and could be improved.
The search function still needs to check each item in the worst case, optimization will only push the number of what gives a usable experience. If the application needs to do text search for a large number of items, it should come up with a way to search them faster and take over the built-in text search.
Yeah, no doubt about that.
Hi, Is there any possibility that this performance issue has been considered and fixed or improved in the ComboBox control itself?
... If the application needs to do text search for a large number of items, it should come up with a way to search them faster and take over the built-in text search.
It seems the internal filtering mechanism is done on UI thread, that's why it's blocking the UI rendering.
But I'm not sure WPF has mechanism to offload such task to non-UI thread, even when you're filtering using CollectionView
.
Hi, Is there any possibility that this performance issue has been considered and fixed or improved in the ComboBox control itself?
This:
and then this:
In your case, it's basically iterating over 40K items done on UI thread. And it's blocking the UI thread, hence the performance delay you noticed.
If 1M items put in the ComboBox
, one would be out of luck... 🤣🤣🤣
That linear search should done on non-UI thread. But first, it can be done by refactoring TextSearch
to be not tightly-coupled to ItemsControl
, or any other UI controls.
But overall, it seems more like design issues in WPF, such as in the case offloading the filtering on CollectionView
to non-UI thread, and so on.
Even I'm not so sure if WinUI would handle such case differently. If not so, then we can learn solution from WinUI to be implemented in WPF.
That linear search should done on non-UI thread.
How often does it happen that someone has more than 40,000 entries in a combo box and not just 1-10? Creating a background task to filter 10 entries is bizarre. I would bet my life that in most scenarios the combo box only has a few entries. To be honest, I've never seen an application in my entire life where a combobox contained a list of more than 40,000 entries. And if that's the case, then I would say it's a design issue. When you have a list that large, you will normally split it up. For example, by creating groups, getting the user to select a group first and then getting a shorter list of items to choose from. But I don't mind if someone comes up with a solution for this niche case. I would just like to add that the combobox needs to deal with short lists in particular. And that should be kept in mind for a possible change.
And if that's the case, then I would say it's a design issue.
Your concern is a question that you should ask the OP yourself, for example, "Why would one add 40K items to a ComboBox
?"
That's a different question. You can ask him directly 😄😄😄
That linear search should be done on non-UI thread. How often does it happen that someone has more than 40,000 entries in a combo box and not just 1-10?
But my answer was for the OP, and directly relevant to the question he asked; and not answering other questions. But if you ask me directly, that would not be a majority use case, although it's not something uncommon.
To be honest, I've never seen an application in my entire life where a combobox contained a list of more than 40,000 entries.
In LOB applications I've seen, they have thousands of customers displayed in a ComboBox
.
Creating a background task to filter 10 entries is bizarre.
And that's not what I exactly have in mind how it could be possibly be achieved/solved.
Let's start with a mindset first of how a good UI should be. One criterion of a good UI is that it should have a good UX with good perceived performance. The concern OP asked here because there seems to be an issue with perceived performance. And that's not good for the UX and UI in overall.
Now let's go to a searching scenario in an app. Searching data in an app is not an uncommon scenario these days. In fact, many users further ask whether they can do instant searching where the results can be shown instantly as they type any letters/characters. Now let's realize first that searching is an expensive task. And as the number of data grows, it becomes a long-running task. A long-running task that is done on UI thread could block the UI rendering, that eventually leads to a not so good, or even poor/bad, perceived performance of the UX and UI.
This case is one example of that.
Another example is CollectionView
filtering issue I mentioned before.
https://stackoverflow.com/questions/851545/wpfs-icollectionview-filter-with-large-sets-of-data
Quoting the SO OP: "But this runs in the UI thread and blocks the entire application when filtering which gives a very poor user experience."
And I believe there are still many unidentified performance issues within WPF code base itself caused by long-running, non-UI-directly-related tasks that actually done on UI thread. Along with other performance issues like UI virtualization issues, data virtualization issues, complex layout and rendering issues, and so on. Common complaints are that WPF becomes slower when displaying large sets of data.
So back to this case, how can this be possibly and ideally solved?
Continuing my earlier suggestion to refactor UI controls out of TextSearch
, we can have ITextSearcher
interface that only focus on searching matching items and returning matching item index in method like int FindMatchingItem(list of required parameters) { }
.
Current TextSearch
logic can still be used by implementing the interface as ComboBoxTextSearcher
, without changing principal implementation technique: searching still done in UI thread, so there's no need to create any unnecessary background thread for example if that really matters.
ComboBox
then can have TextSearcher
property of ITextSearcher
type that has ComboBoxTextSearcher
set as the default implementation.
But then developer can extend ITextSearcher
and have custom text search implementation done on non-UI thread for better UX and UI perceived performance.
One can even use text search engine libraries like Lucene.NET (https://lucenenet.apache.org/), for example.
Or whatever very sophisticated custom search implementation could possibly be needed and done to make a great UI with excellent UX and perceived performance.
The limit is only your imagination.
Afterall, engineering challenges and solutions should focus first on how to make a great UI with excellent UX and perceived performance.
Description
When loading 40,000 complex objects and setting the DisplayMemberPath, there is a delay between the keystroke and the update of the letter in the ComboBox control. Please find the code snippet below.
XAML codes:
C# Code:
Video output:
https://github.com/user-attachments/assets/c6434c23-ec2f-4344-9d76-b0ac482d187e
Tested Sample: ComboBox_Demo.zip
Reproduction Steps
Expected behavior
There should not be a delay when entering a letter into the ComboBox control.
Actual behavior
There should be a delay when entering a letter into the ComboBox control.
Regression?
No response
Known Workarounds
No response
Impact
No response
Configuration
No response
Other information
No response