103 lines
3.7 KiB
C#
103 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using JD.Core;
|
|
|
|
namespace JD.WPF.Controls
|
|
{
|
|
public static class ListBoxExtensions
|
|
{
|
|
private static readonly Dictionary<ListBox, AutoScrollInfo> m_activeControls = new Dictionary<ListBox, AutoScrollInfo>();
|
|
|
|
public static readonly DependencyProperty ScrollOnNewItemProperty = DependencyProperty.RegisterAttached("ScrollOnNewItem", typeof(bool), typeof(ListBoxExtensions), new UIPropertyMetadata(false, OnScrollOnNewItemChanged));
|
|
|
|
public static bool GetScrollOnNewItem(DependencyObject obj)
|
|
{
|
|
return (bool)obj.GetValue(ScrollOnNewItemProperty);
|
|
}
|
|
|
|
public static void SetScrollOnNewItem(DependencyObject obj, bool value)
|
|
{
|
|
obj.SetValue(ScrollOnNewItemProperty, value);
|
|
}
|
|
|
|
private static void OnScrollOnNewItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
ListBox listBox = d as ListBox;
|
|
if (listBox == null) return;
|
|
bool oldValue = (bool)e.OldValue, newValue = (bool)e.NewValue;
|
|
if (newValue == oldValue) return;
|
|
if (newValue)
|
|
{
|
|
if (listBox.IsLoaded)
|
|
OnListBoxLoaded(listBox, new RoutedEventArgs());
|
|
else
|
|
listBox.Loaded += new RoutedEventHandler(OnListBoxLoaded);
|
|
listBox.Unloaded += new RoutedEventHandler(OnListBoxUnloaded);
|
|
}
|
|
else
|
|
{
|
|
OnListBoxUnloaded(listBox, new RoutedEventArgs());
|
|
}
|
|
}
|
|
|
|
private static void OnListBoxLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
ListBox listBox = (ListBox)sender;
|
|
INotifyCollectionChanged notifyableCollection = listBox.ItemsSource as INotifyCollectionChanged;
|
|
if (notifyableCollection == null)
|
|
{
|
|
CodeHelper.DebugBreak("Trying to activate scroll on added item feature whereas the collection behind does not implement INotifyCollectionChanged. ");
|
|
return;
|
|
}
|
|
|
|
listBox.Loaded -= OnListBoxLoaded;
|
|
m_activeControls[listBox] = new AutoScrollInfo(listBox);
|
|
}
|
|
|
|
private static void OnListBoxUnloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
ListBox listBox = (ListBox)sender;
|
|
if (m_activeControls.ContainsKey(listBox))
|
|
{
|
|
m_activeControls[listBox].Dispose();
|
|
m_activeControls.Remove(listBox);
|
|
}
|
|
listBox.Unloaded -= OnListBoxUnloaded;
|
|
}
|
|
|
|
private class AutoScrollInfo : IDisposable
|
|
{
|
|
public readonly ListBox m_listBox;
|
|
public readonly INotifyCollectionChanged m_notifyableCollection;
|
|
|
|
public AutoScrollInfo(ListBox listBox)
|
|
{
|
|
m_listBox = listBox;
|
|
m_notifyableCollection = listBox.ItemsSource as INotifyCollectionChanged;
|
|
if (m_notifyableCollection != null)
|
|
{
|
|
m_notifyableCollection.CollectionChanged += OnCollectionChanged;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (m_notifyableCollection != null)
|
|
{
|
|
m_notifyableCollection.CollectionChanged -= OnCollectionChanged;
|
|
}
|
|
}
|
|
|
|
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
|
{
|
|
if (e.Action == NotifyCollectionChangedAction.Add)
|
|
{
|
|
m_listBox.ScrollIntoView(e.NewItems[0]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|