VirtualizationMode="Recycling" Issue And Hackish Fix??
-
Source: http://www.fileplay.net/file/15671/highlightsearchedtextinlistview[^] Hi, Normally i'd try to strip code down to it's minimum and post it here, but this is one of those instances where the bare minimum = 6 files so please pardon the need to download ;P The Setup: Their's a listview with 3000 items with virtualization enabled in recycling mode. The ItemsSource property is bound to a collection of elements of type "Person". In the MainWindow i setup DataTemplates so the "Person" instances are represented by a custom control called "HighlightTextBlock" [it highlights portions of its text with a colored background if it matches its "HighlightPhrase" dependency property]. In MainWindow.xaml.cs the "FilterItems(...)" function uses a CollectionView to filter items so only ones with highlighted text are shown in the list. The Issue: If you type some letters into the search box and then scroll down then you will see lots of items where the highlighting doesn't occur. Interestingly the problem doesn't occur if you enlarge the window to show more items. The Hackish Fix: In HighlightTextBlock.cs, in the OnHighlightPhraseChanged(...) function [which fires when its associated dependency property "HighlightPhrase" changes], i found that the presence of this code "fixes" the problem:
tb.Text = tb.Text;
Btw trying things like
tb.InvalidateVisual();
had no effect here, and the HighlightPhraseProperty is using
FrameworkPropertyMetadataOptions.AffectsRender
The Crappy Fix: If VirtualizingStackPanel.VirtualizationMode="Standard" is used then the problem goes away (without using the Hackish Fix). Interestingly this guy had issues while scrolling with recycling-virtualization mode that didn't manifest when recycling-standard mode was used: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a4792b31-0a0d-49e1-bcf1-62bb8e4e5326/[^] Not Filtering With Collection Fix: The problem goes away if the contents of the "FilterItems(...)" function, in MainWindow.xam
-
Source: http://www.fileplay.net/file/15671/highlightsearchedtextinlistview[^] Hi, Normally i'd try to strip code down to it's minimum and post it here, but this is one of those instances where the bare minimum = 6 files so please pardon the need to download ;P The Setup: Their's a listview with 3000 items with virtualization enabled in recycling mode. The ItemsSource property is bound to a collection of elements of type "Person". In the MainWindow i setup DataTemplates so the "Person" instances are represented by a custom control called "HighlightTextBlock" [it highlights portions of its text with a colored background if it matches its "HighlightPhrase" dependency property]. In MainWindow.xaml.cs the "FilterItems(...)" function uses a CollectionView to filter items so only ones with highlighted text are shown in the list. The Issue: If you type some letters into the search box and then scroll down then you will see lots of items where the highlighting doesn't occur. Interestingly the problem doesn't occur if you enlarge the window to show more items. The Hackish Fix: In HighlightTextBlock.cs, in the OnHighlightPhraseChanged(...) function [which fires when its associated dependency property "HighlightPhrase" changes], i found that the presence of this code "fixes" the problem:
tb.Text = tb.Text;
Btw trying things like
tb.InvalidateVisual();
had no effect here, and the HighlightPhraseProperty is using
FrameworkPropertyMetadataOptions.AffectsRender
The Crappy Fix: If VirtualizingStackPanel.VirtualizationMode="Standard" is used then the problem goes away (without using the Hackish Fix). Interestingly this guy had issues while scrolling with recycling-virtualization mode that didn't manifest when recycling-standard mode was used: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a4792b31-0a0d-49e1-bcf1-62bb8e4e5326/[^] Not Filtering With Collection Fix: The problem goes away if the contents of the "FilterItems(...)" function, in MainWindow.xam
Ok i figured it out. It has to do with the Text property. It gets changed when the items get recycled, when scrolling the list, and for some reason the "HighlightPhrase" property doesn't also get set when doing this and apparently this isn't an issue because the value of "HighlightPhrase" doesn't change when scrolling anyway. It just works, now ;P This is what makes it work (note: "new" keyword usage because this class inherits TextBlock):
public new string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public new static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(HighlightTextBlock), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(UpdateHighlighting))); private static void UpdateHighlighting(DependencyObject d, DependencyPropertyChangedEventArgs e) { ApplyHighlight(d as HighlightTextBlock); }
See article for latest code: Highlight Searched Text in WPF ListView[^]