2012-08-22 35 views

回答

4

如果实现IScrollInfo可以覆盖MouseWheelUpMouseWheelLeft ,下\右中同样的方式

编辑(更简单):

添加到您的ScrollViewer PreviewMouseWheel

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

     } 

xaml:

<ScrollViewer x:Name="myScrollViewer" HorizontalScrollBarVisibility="Visible" Mouse.PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> 
+0

你的意思是像内部控制?通过“自定义”我的意思是我有一个自定义模板。您的解决方案是否需要实现从WPF ListView继承的新ListView类? – jacek11

+0

我的解决方案意味着您在自定义面板上实现了scrollinfo并使用面板 – ZSH

+0

而不是listview? – jacek11

3

这应该使用Behavior来实现更高的可重用性。而且,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); 
    } 
} 

你需要添加下列引用: System.WindowsSystem.Windows.ControlsSystem.Windows.Input,你可能需要获得混合SDK NuGet包,查找和引用大会的System.Windows.Interactivity DLL扩展部分。

使用此为VisualTreeHelpers

public class VisualTreeHelpers 
{ 
    /// <summary> 
    /// Return the first visual child of element by type. 
    /// </summary> 
    /// <typeparam name="T">The type of the Child</typeparam> 
    /// <param name="obj">The parent Element</param> 
    public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject 
    { 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
      if (child != null && child is T) 
       return (T)child; 
      else 
      { 
       T childOfChild = FindVisualChild<T>(child); 
       if (childOfChild != null) 
        return childOfChild; 
      } 
     } 
     return null; 
    } 
} 

参考:https://codereview.stackexchange.com/questions/44760/is-there-a-better-way-to-get-a-child

请注意,这是不一样的Windows.System.MediaVisualTreeHelper

下面是如何使用它在XAML:

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

i命名空间被声明为xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

behaviors被声明为

xmlns:behaviors="clr-namespace:MyNamespace"

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

+0

+1,因为它为我节省了大量的时间来寻找正确的解决方案。顺便说一句,这里是'VisualTreeHelpers'实现的链接:http://codereview.stackexchange.com/questions/44760/is-there-a-better-way-to-get-a-child –

+0

发现'我'也可以像这样引用:'xmlns:i =“clr-namespace:System.Windows.Interactivity; assembly = System.Windows.Interactivity”' – vapcguy