如何启用鼠标的水平滚动?

54 浏览
0 Comments

如何启用鼠标的水平滚动?

我无法确定如何使用鼠标滚轮进行水平滚动。垂直滚动可以自动完成,但我需要水平滚动我的内容。我的代码如下:


    
        
            
        
    

我的项模板如下:


    
        
            
                
                    
                        
                            
                                
                                
                            
                        
                    
                
                
                    
                        
                        
                    
                
            
        
              

是否需要添加其他方法或控件来实现这个功能?

0
0 Comments

问题出现的原因:需要在包含ScrollViewer的每个ItemsControl上启用水平滚动。

解决方法:编写了一个用于此目的的附加属性,以便在每个包含ScrollViewer的ItemsControl上重用它。在PreviewMouseWheel事件处理程序中,使用FindChildByType方法查找ScrollViewer,并根据鼠标滚轮的方向调用相应的滚动方法。通过设置附加属性的值,可以控制是否启用水平滚动。这个实现在第一次尝试时成功,并且非常简单,只需将此行为添加到想要添加的控件上即可。

0
0 Comments

问题的出现原因是用户想要通过鼠标实现水平滚动,但是在没有ScrollViewer的情况下不知道如何添加PreviewMouseWheel事件。

解决方法是通过将PreviewMouseWheel事件添加到ScrollViewer中,并检查Shift键是否按下(或者其他你想要指示水平滚动的方式),然后根据MouseWheelEventArgs的Delta值调用LineLeft或LineRight(或者PageLeft/PageRight)。

用户提出了一个问题,即在没有ScrollViewer的情况下如何添加PreviewMouseWheel事件。其他用户回答说,ListBox的控件模板中应该有一个ScrollViewer,所以像ScrollViewer.VerticalScrollBarVisibility="Disabled"这样的附加属性可以起作用。

然而,问题仍然存在,即如何在不重写控件模板的情况下附加ScrollViewer的PreviewMouseWheel事件(因为这样会破坏自动操作系统相关的主题)。

其他用户猜测可能需要遍历可视化树来找到ScrollViewer(不确定,因为这个答案已经是3年前的了)。

0
0 Comments

如何使用鼠标启用水平滚动?

问题的出现原因:代码中存在一些bug,例如没有过滤Shift键、同时水平和垂直滚动(运动为对角线)以及无法通过将属性设置为false来禁用该行为。

解决方法:将下面的代码添加到您的代码中,然后在XAML中,在任何包含ScrollViewer的UIElement上将附加属性设置为true。

public static class ScrollViewerHelper
{
    public static readonly DependencyProperty ShiftWheelScrollsHorizontallyProperty
        = DependencyProperty.RegisterAttached("ShiftWheelScrollsHorizontally",
            typeof(bool),
            typeof(ScrollViewerHelper),
            new PropertyMetadata(false, UseHorizontalScrollingChangedCallback));
    private static void UseHorizontalScrollingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as UIElement;
        if (element == null)
            throw new Exception("Attached property must be used with UIElement.");
        if ((bool)e.NewValue)
            element.PreviewMouseWheel += OnPreviewMouseWheel;
        else
            element.PreviewMouseWheel -= OnPreviewMouseWheel;
    }
    private static void OnPreviewMouseWheel(object sender, MouseWheelEventArgs args)
    {
        var scrollViewer = ((UIElement)sender).FindDescendant();
        if (scrollViewer == null)
            return;
        if (Keyboard.Modifiers != ModifierKeys.Shift)
            return;
        if (args.Delta < 0)
            scrollViewer.LineRight();
        else
            scrollViewer.LineLeft();
        args.Handled = true;
    }
    public static void SetShiftWheelScrollsHorizontally(UIElement element, bool value) => element.SetValue(ShiftWheelScrollsHorizontallyProperty, value);
    public static bool GetShiftWheelScrollsHorizontally(UIElement element) => (bool)element.GetValue(ShiftWheelScrollsHorizontallyProperty);
    [CanBeNull]
    private static T FindDescendant([CanBeNull] this DependencyObject d) where T : DependencyObject
    {
        if (d == null)
            return null;
        var childCount = VisualTreeHelper.GetChildrenCount(d);
        for (var i = 0; i < childCount; i++)
        {
            var child = VisualTreeHelper.GetChild(d, i);
            var result = child as T ?? FindDescendant(child);
            if (result != null)
                return result;
        }
        return null;
    }
}

以上是一种完整的行为。将上述类添加到您的代码中,然后在XAML中,在任何包含ScrollViewer的UIElement上将附加属性设置为true。


在解决方法中还提到了一些问题和修改方法,例如在XAML文件中出现的错误,需要设置一个xmlns,以映射到该类的CLR命名空间。还提到了Get和Set属性的名称错误问题,需要将其更改为"SetShiftWheelScrollsHorizontally"和"GetShiftWheelScrollsHorizontally"。另外还提到了使用"LineRight()"和"LineLeft()"可能会比较慢,可以使用"scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + -args.Delta)"来代替。最后还指出了代码中引用了ItemsControl,但答案中说"将附加属性设置为true的任何包含ScrollViewer的UIElement"。解决方法是将UIElement替换为ItemsControl。

希望以上内容对您有所帮助。

0