wabbajack/Wabbajack/Util/AutoScrollBehavior.cs

116 lines
4.1 KiB
C#
Raw Normal View History

2019-07-22 22:17:46 +00:00
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace Wabbajack
{
2019-09-14 04:35:42 +00:00
internal class AutoScrollBehavior
2019-07-22 22:17:46 +00:00
{
2019-09-14 04:35:42 +00:00
private static readonly Dictionary<ListBox, Capture> Associations =
new Dictionary<ListBox, Capture>();
public static readonly DependencyProperty ScrollOnNewItemProperty =
DependencyProperty.RegisterAttached(
"ScrollOnNewItem",
typeof(bool),
typeof(AutoScrollBehavior),
new UIPropertyMetadata(false, OnScrollOnNewItemChanged));
2019-07-22 22:17:46 +00:00
public static bool GetScrollOnNewItem(DependencyObject obj)
{
2019-10-07 17:33:34 +00:00
return (bool)obj.GetValue(ScrollOnNewItemProperty);
2019-07-22 22:17:46 +00:00
}
public static void SetScrollOnNewItem(DependencyObject obj, bool value)
{
obj.SetValue(ScrollOnNewItemProperty, value);
}
public static void OnScrollOnNewItemChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var listBox = d as ListBox;
if (listBox == null) return;
2019-10-07 17:33:34 +00:00
bool oldValue = (bool)e.OldValue, newValue = (bool)e.NewValue;
2019-07-22 22:17:46 +00:00
if (newValue == oldValue) return;
if (newValue)
{
listBox.Loaded += ListBox_Loaded;
listBox.Unloaded += ListBox_Unloaded;
var itemsSourcePropertyDescriptor = TypeDescriptor.GetProperties(listBox)["ItemsSource"];
itemsSourcePropertyDescriptor.AddValueChanged(listBox, ListBox_ItemsSourceChanged);
}
else
{
listBox.Loaded -= ListBox_Loaded;
listBox.Unloaded -= ListBox_Unloaded;
if (Associations.ContainsKey(listBox))
Associations[listBox].Dispose();
var itemsSourcePropertyDescriptor = TypeDescriptor.GetProperties(listBox)["ItemsSource"];
itemsSourcePropertyDescriptor.RemoveValueChanged(listBox, ListBox_ItemsSourceChanged);
}
}
private static void ListBox_ItemsSourceChanged(object sender, EventArgs e)
{
2019-10-07 17:33:34 +00:00
var listBox = (ListBox)sender;
2019-07-22 22:17:46 +00:00
if (Associations.ContainsKey(listBox))
Associations[listBox].Dispose();
Associations[listBox] = new Capture(listBox);
}
2019-09-14 04:35:42 +00:00
private static void ListBox_Unloaded(object sender, RoutedEventArgs e)
2019-07-22 22:17:46 +00:00
{
2019-10-07 17:33:34 +00:00
var listBox = (ListBox)sender;
2019-07-22 22:17:46 +00:00
if (Associations.ContainsKey(listBox))
Associations[listBox].Dispose();
listBox.Unloaded -= ListBox_Unloaded;
}
2019-09-14 04:35:42 +00:00
private static void ListBox_Loaded(object sender, RoutedEventArgs e)
2019-07-22 22:17:46 +00:00
{
2019-10-07 17:33:34 +00:00
var listBox = (ListBox)sender;
2019-07-22 22:17:46 +00:00
var incc = listBox.Items as INotifyCollectionChanged;
if (incc == null) return;
listBox.Loaded -= ListBox_Loaded;
Associations[listBox] = new Capture(listBox);
}
2019-09-14 04:35:42 +00:00
private class Capture : IDisposable
2019-07-22 22:17:46 +00:00
{
2019-11-21 15:45:00 +00:00
private readonly INotifyCollectionChanged _incc;
private readonly ListBox _listBox;
2019-07-22 22:17:46 +00:00
public Capture(ListBox listBox)
{
2019-11-21 15:45:00 +00:00
this._listBox = listBox;
_incc = listBox.ItemsSource as INotifyCollectionChanged;
if (_incc != null) _incc.CollectionChanged += incc_CollectionChanged;
2019-09-14 04:35:42 +00:00
}
public void Dispose()
{
2019-11-21 15:45:00 +00:00
if (_incc != null)
_incc.CollectionChanged -= incc_CollectionChanged;
2019-07-22 22:17:46 +00:00
}
2019-09-14 04:35:42 +00:00
private void incc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
2019-07-22 22:17:46 +00:00
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
try
{
_listBox.ScrollIntoView(e.NewItems[0]);
_listBox.SelectedItem = e.NewItems[0];
}
catch (ArgumentOutOfRangeException) { }
2019-07-22 22:17:46 +00:00
}
}
}
}
}