I've got a long list of items which I'd like to filter. I've added an IsFiltered property to the view model in my list. Using an ItemContainerStyle I'm able to bind the ListViewItem's visibility to the IsFiltered property.
<ListView ItemsSource="{Binding Path=MyItems}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsFiltered}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
All works well and changing the IsFiltered property properly reflects on the UI. I'm running a background process to determine which items to filter and when it completes the IsFiltered property of each of the view model items gets updated on the UI thread. The problem is that due to the high number of PropertyChanged events being fired there is a very noticeable pause. I've managed to alleviate this by using
public bool IsFiltered
{
get
{
return m_IsFiltered;
}
set
{
if (m_IsFiltered == value)
{
return;
}
m_IsFiltered = value;
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Background,
(System.Action)(() => RaisePropertyChanged("IsFiltered")));
}
}
in the view model. The RaisePropertyChanged simply raises the PropertyChanged event.
I'm try to restrict knowledge of the UI framework (WPF) from the view model. In this case I'd like to just have the RaisePropertyChanged call and somehow give the UI the responsibility to listen to the property change in an asynchronous manner. Is this possible? It isn't very critical that the event gets handled as the property changed gets fired.
I've tried adding IsAsync=True to the DataTrigger's binding, but this does not have the intended effect.