// ADD this variable to the class:
private INotifyCollectionChanged prevListViewItemsSource;
public ListViewLayoutManager(ListView listView)
{
if ( listView == null )
{
throw new ArgumentNullException( "listView" );
}
this.listView = listView;
this.listView.Loaded += new RoutedEventHandler( ListViewLoaded );
this.listView.Unloaded += new RoutedEventHandler( ListViewUnloaded );
// ADD from the following lines and methods:
DependencyPropertyDescriptor dpd =
DependencyPropertyDescriptor.FromProperty(ListView.ItemsSourceProperty, typeof(ListView));
dpd.AddValueChanged(this.listView, ListViewItemsSourceChanged);
ListViewItemsSourceChanged(null, null);
} // ListViewLayoutManager
private void ListViewItemsSourceChanged(object sender, EventArgs e)
{
if (prevListViewItemsSource != null)
{
prevListViewItemsSource.CollectionChanged -= source_CollectionChanged;
}
var source = listView.ItemsSource as INotifyCollectionChanged;
prevListViewItemsSource = source;
if (source != null)
{
source.CollectionChanged += source_CollectionChanged;
}
}
private void source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ResetColumnWidths();
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (object o in e.NewItems)
{
var item = o as INotifyPropertyChanged;
if (item != null)
{
item.PropertyChanged += item_PropertyChanged;
}
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (object o in e.OldItems)
{
var item = o as INotifyPropertyChanged;
if (item != null)
{
item.PropertyChanged -= item_PropertyChanged;
}
}
break;
case NotifyCollectionChangedAction.Replace:
foreach (object o in e.OldItems)
{
var item = o as INotifyPropertyChanged;
if (item != null)
{
item.PropertyChanged -= item_PropertyChanged;
}
}
foreach (object o in e.NewItems)
{
var item = o as INotifyPropertyChanged;
if (item != null)
{
item.PropertyChanged += item_PropertyChanged;
}
}
break;
case NotifyCollectionChangedAction.Reset:
var list = sender as IEnumerable;
if (list != null)
{
foreach (object o in list)
{
var item = o as INotifyPropertyChanged;
if (item != null)
{
item.PropertyChanged += item_PropertyChanged;
}
}
}
break;
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
ResetColumnWidths();
}
private void ResetColumnWidths()
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action) (() =>
{
GridView view = listView.View as GridView;
if (view != null)
{
listView.UpdateLayout(); // Prevent flickering on expanding columns (not collapsing though)
foreach (GridViewColumn gridViewColumn in view.Columns)
{
bool? isFillColumn = RangeColumn.GetRangeIsFillColumn(gridViewColumn);
if (!isFillColumn.HasValue || !isFillColumn.Value)
{
if (double.IsNaN(gridViewColumn.Width))
{
gridViewColumn.Width = gridViewColumn.ActualWidth;
gridViewColumn.Width = double.NaN;
}
}
}
}
Dispatcher.CurrentDispatcher.BeginInvoke((Action) Refresh, DispatcherPriority.Render);
}), DispatcherPriority.Render);
}