Wednesday, March 31, 2010

AutoRefreshCollectionViewSource Tweaks

A few posts back, I listed the AutoRefreshCollectionViewSource class that extends the CollectionViewSource class by causing its sort to automatically refresh when needed (i.e., a sorted on property is changed).  After implementing it I discovered the need for a tweak to allow the controls to call ScrollIntoView in response to a Refresh (otherwise the SelectedItem might get pushed up or down the ListBox and out of view!).  At first I tried to call ScrollIntoView from various other control events, but I found that these events fired before Binding caused the underlying objects to be updated and the CollectionViewSource was refreshed.  The solution that I came up with was to add a custom event to the AutoRefreshCollectionViewSource object:

public delegate void RefreshEventHandler();
public event RefreshEventHandler RefreshEvent;
...
private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
...
    if (refresh)
    {
      View.Refresh();
      RefreshEvent();
    }
...

I then added an overload to the WPFCollection<T>.GetCollectionView() method that would handle setting up an event listener:


public ListCollectionView GetCollectionView(AutoRefreshCollectionViewSource arcvs, AutoRefreshCollectionViewSource.RefreshEventHandler handler)
{
  arcvs.RefreshEvent += new AutoRefreshCollectionViewSource.RefreshEventHandler(handler);
  return GetCollectionView(arcvs);
}


The handler simply calls the ListBox.ScrollIntoView on the currently SelectedItem.  Seems to solve the problem.

No comments:

Post a Comment