諾禾致源、[WPF]使用附加屬性處理 ScrollViewer 的滾動輪劫持問題

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();
          }
      };
}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章