Wpf 在ListView上使用鼠标激活水平滚动

Wpf 在ListView上使用鼠标激活水平滚动,wpf,listview,scroll,mouse,Wpf,Listview,Scroll,Mouse,我有一个自定义的水平ListView,它的模板中有自定义的ScrollViewer(使用Blend创建)。我希望它在使用鼠标滚轮时水平滚动。 我该怎么做呢?如果您实现了IScrollInfo,您可以覆盖mouseweelUp来执行mouseweelLeft 以同样的方式向下\向右移动 编辑(更简单): 添加到ScrollViewer预览鼠标滚轮 private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventAr

我有一个自定义的水平ListView,它的模板中有自定义的ScrollViewer(使用Blend创建)。我希望它在使用鼠标滚轮时水平滚动。
我该怎么做呢?

如果您实现了
IScrollInfo
,您可以覆盖
mouseweelUp
来执行
mouseweelLeft
以同样的方式向下\向右移动

编辑(更简单):

添加到ScrollViewer预览鼠标滚轮

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta < 0) // wheel down
            {
                if (myScrollViewer.HorizontalOffset + e.Delta > 0)
                {
                    myScrollViewer.ScrollToHorizontalOffset(myScrollViewer.HorizontalOffset + e.Delta);  
                }
                else
                {
                    myScrollViewer.ScrollToLeftEnd();
                }
            }
            else //wheel up
            {
                if (myScrollViewer.ExtentWidth > myScrollViewer.HorizontalOffset + e.Delta)
                {
                    myScrollViewer.ScrollToHorizontalOffset(myScrollViewer.HorizontalOffset + e.Delta);  
                }
                else
                {
                    myScrollViewer.ScrollToRightEnd();
                }
            }

        }
private void ScrollViewer\u预览鼠标滚轮(对象发送器,鼠标滚轮事件参数e)
{
如果(e.Delta<0)//车轮放下
{
如果(myScrollViewer.HorizontalOffset+e.Delta>0)
{
ScrollToHorizontalOffset(myScrollViewer.HorizontalOffset+e.Delta);
}
其他的
{
myScrollViewer.ScrollToLeftEnd();
}
}
否则,开车
{
if(myScrollViewer.ExtentWidth>myScrollViewer.HorizontalOffset+e.Delta)
{
ScrollToHorizontalOffset(myScrollViewer.HorizontalOffset+e.Delta);
}
其他的
{
myScrollViewer.ScrollToRightEnd();
}
}
}
xaml:


这应该通过
行为来实现,以提高重用性。此外,ZSH的逻辑是冗余的,可以简化。这是我的密码:

/// <summary>
/// Allows an <see cref="ItemsControl"/> to scroll horizontally by listening to the
/// <see cref="PreviewMouseWheel"/> event of its internal <see cref="ScrollViewer"/>.
/// </summary>
public class HorizontalScrollBehavior : Behavior<ItemsControl>
{
    /// <summary>
    /// A reference to the internal ScrollViewer.
    /// </summary>
    private ScrollViewer ScrollViewer { get; set; }

    /// <summary>
    /// By default, scrolling down on the wheel translates to right, and up to left.
    /// Set this to true to invert that translation.
    /// </summary>
    public bool IsInverted { get; set; }

    /// <summary>
    /// The ScrollViewer is not available in the visual tree until the control is loaded.
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Loaded -= OnLoaded;

        ScrollViewer = VisualTreeHelpers.FindVisualChild<ScrollViewer>(AssociatedObject);

        if (ScrollViewer != null)
        {
            ScrollViewer.PreviewMouseWheel += OnPreviewMouseWheel;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        if (ScrollViewer != null)
        {
            ScrollViewer.PreviewMouseWheel -= OnPreviewMouseWheel;
        }
    }

    private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        var newOffset = IsInverted ?
            ScrollViewer.HorizontalOffset + e.Delta :
            ScrollViewer.HorizontalOffset - e.Delta;

        ScrollViewer.ScrollToHorizontalOffset(newOffset);
    }
}
参考:

请注意,它与
Windows.System.Media
中的
visualtreeheloper
不同

以下是如何在XAML中使用它:

<ListBox>
    <i:Interaction.Behaviors>
        <behaviors:HorizontalScrollBehavior />
    </i:Interaction.Behaviors>
</ListBox>

其中
i
名称空间声明为
xmlns:i=”http://schemas.microsoft.com/expression/2010/interactivity“

行为
声明为

xmlns:behaviors=“clr namespace:MyNamespace”


其中
MyNamespace
是包含
HorizontalScrollBehavior
类的名称空间。

我一直在寻找最简单的方法,让任何
ScrollViewer
从上到下滚动。这里是其他答案的最简单组合

<ScrollViewer HorizontalScrollBarVisibility="Visible"
              PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 

以及:

private void ScrollViewer\u预览鼠标滚轮(对象发送器,鼠标滚轮事件参数e)
{
ScrollViewer ScrollViewer=(ScrollViewer)发送方;
如果(e.Delta<0)
{
scrollViewer.LineRight();
}
其他的
{
scrollViewer.LineLeft();
}
e、 已处理=正确;
}

Xaml代码:

<ScrollViewer HorizontalScrollBarVisibility="Visible" 
              VerticalScrollBarVisibility="Visible" 
              PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 
</ScrollViewer>

你是说在控制范围内?“自定义”是指我有一个自定义模板。您的解决方案是否需要实现从WPF ListView继承的新ListView类?我的解决方案意味着您在自定义面板上实现scrollinfo并使用该面板,但仍然不知道将其放置在何处。我的代码如下所示:。。。代码中的其余部分behindi无法从resource dictionary+1中的样式中访问隐藏的代码,因为这节省了我大量时间来搜索正确的解决方案。顺便说一句,这里是VisualTreeHelpers实现的链接:发现
i
也可以这样引用:
xmlns:i=“clr名称空间:System.Windows.Interactivity;assembly=System.Windows.Interactivity”
<ScrollViewer HorizontalScrollBarVisibility="Visible"
              PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    ScrollViewer scrollViewer = (ScrollViewer)sender;
    if (e.Delta < 0)
    {
        scrollViewer.LineRight();
    }
    else
    {
        scrollViewer.LineLeft();
    }
    e.Handled = true;
}
<ScrollViewer HorizontalScrollBarVisibility="Visible" 
              VerticalScrollBarVisibility="Visible" 
              PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 
</ScrollViewer>
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    var scrollViewer = (ScrollViewer)sender;
    if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
    {
        scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - e.Delta);
        e.Handled = true;
    }
}