tags:

views:

30

answers:

1

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.

A: 

IsAsync is good, but you should determine correctly which one of your property change (caused by assignement of new data) require long running task, then put it there. CMIIW IsAsync on your data trigger binding didn't work because to to perform changes on IsFiltered is only a simple task don't require long running task.

So find out which one of the property change possibly took long running task put the IsAsync = True there.

Hope that help.

ktutnik
It doesn't really help. As you rightly point out getting a bool is not really a slow operation. The problem is that I've created a situation where a large number of PropertyChanged events are being fired at the end of a bulk operation. I'll probably have to split the bulk operation up, which will also slice up the IsFiltered updates and allow the rest of the UI a chance to update also. I don't think I want to try leveraging IsAsync, since it wasn't really intended for this kind of usage.
Christo