[WPF]使用附加属性处理 ScrollViewer 的滚动轮劫持问题
2023-09-11 14:16:13 时间
之前写过一篇博客 关于 ScrollViewer 和滚动轮劫持(scroll-wheel-hijack),里面介绍了 ScrollViewer 的滚动轮劫持问题,以及如果解决。当时的做法是继承 ScrollViewer 并重写 OnMouseWheel,全部代码如下:
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 ,全部代码如下:
public class ScrollViewerService
{
/// <summary>
/// 从指定元素获取 CanScrollOuter 依赖项属性的值。
/// </summary>
/// <param name="obj">从中读取属性值的元素。</param>
/// <returns>从属性存储获取的属性值。</returns>
public static bool GetCanScrollOuter(DependencyObject obj) => (bool)obj.GetValue(CanScrollOuterProperty);
/// <summary>
/// 将 CanScrollOuter 依赖项属性的值设置为指定元素。
/// </summary>
/// <param name="obj">对其设置属性值的元素。</param>
/// <param name="value">要设置的值。</param>
public static void SetCanScrollOuter(DependencyObject obj, bool value) => obj.SetValue(CanScrollOuterProperty, value);
/// <summary>
/// 标识 CanScrollOuter 依赖项属性。
/// </summary>
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<ScrollViewer>().FirstOrDefault();
if (parent == null)
return;
if (e.Delta < 0)
parent.LineDown();
else
parent.LineUp();
}
};
}
}
处理不够优雅,但将就着用吧。
参考
ScrollViewer.OnMouseWheel(MouseWheelEventArgs) Method (System.Windows.Controls) Microsoft Docs
MouseWheelEventArgs.Delta Property (System.Windows.Input) Microsoft Docs
ScrollViewer.ExtentHeight Property (System.Windows.Controls) Microsoft Docs
ScrollViewer.ViewportHeight Property (System.Windows.Controls) Microsoft Docs
ScrollViewer.VerticalOffset Property (System.Windows.Controls) Microsoft Docs
相关文章
- 如何创建一个基于 .NET Core 3 的 WPF 项目
- WPF入门教程系列十一——依赖属性(一)
- WPF入门教程系列五——Window 介绍
- [译]聊聊C#中的泛型的使用(新手勿入) Seaching TreeVIew WPF 可编辑树Ztree的使用(包括对后台数据库的增删改查) 字段和属性的区别 C# 遍历Dictionary并修改其中的Value 学习笔记——异步 程序员常说的「哈希表」是个什么鬼?
- Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作
- 【wpf】MouseLeftButtonDown
- WPF Binding设计的感悟
- WPF整理-使用用户选择主题的颜色和字体
- WPF中Window.Owner属性详解
- WPF中焦点详解
- 创建WPF项目
- 【C#/WPF】图片的切割/切图/裁剪图片
- 【WPF】Button按钮添加背景图片
- 【WPF】C#代码动态添加控件的Margin属性