public class ExtendedScrollViewer : ScrollViewer
{
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (ViewportHeight + VerticalOffset >= ExtentHeight && e.Delta <= 0)
return;
if (VerticalOffset == 0 && e.Delta >= 0)
return;
base.OnMouseWheel(e);
}
}
最近有人提到能不能運用附加屬性處置,所以我就試試。暫時發現簡單地用附加屬性處置,除非查找 VisualTree 上的父節點 ScrollView 並調用它的 LineUp 和 LineDown ,全部代碼如下:
Copy
public class ScrollViewerService
{
///
/// 從指定元素獲取 CanScrollOuter 依賴項屬性的值。
///
/// 從中讀取屬性值的元素。
/// 附屬性存儲獲取的屬性值。
public static bool GetCanScrollOuter(DependencyObject obj) => (bool)obj.GetValue(CanScrollOuterProperty);
///
/// 將 CanScrollOuter 依賴項屬性的值設置爲指定元素。
///
/// 對其設置屬性值的元素。
/// 要設置的值。
public static void SetCanScrollOuter(DependencyObject obj, bool value) => obj.SetValue(CanScrollOuterProperty, value);
///
/// 標識 CanScrollOuter 依賴項屬性。
///
public static readonly DependencyProperty CanScrollOuterProperty =
DependencyProperty.RegisterAttached("CanScrollOuter", typeof(bool), typeof(ScrollViewerService), new PropertyMetadata(default(bool), OnCanScrollOuterChanged));
private static void OnCanScrollOuterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var oldValue = (bool)args.OldValue;
var newValue = (bool)args.NewValue;
if (newValue == false)
return;
var target = obj as ScrollViewer;
target.PreviewMouseWheel += (s, e) =>
{
if (target.ViewportHeight + target.VerticalOffset >= target.ExtentHeight && e.Delta <= 0
|| target.VerticalOffset == 0 && e.Delta >= 0)
{
var parent = target.GetVisualAncestors().OfType().FirstOrDefault();
if (parent == null)
return;
if (e.Delta < 0)
parent.LineDown();
else
parent.LineUp();
}
};
}
}