English 中文(简体)
• 如何利用 mo带轮机在计生联中横向发展?
原标题:How to horizontally scroll in WPF using mouse tilt wheel?
  • 时间:2010-11-11 18:50:06
  •  标签:
  • c#
  • wpf

你们如何使世界森林基金能够利用 mo带轮对横向滚动作出反应? 例如,我有一个Microsoft Exploration miniuse,并尝试了一个带有星号的光盘中包含的横向滚动内容。

HorizontalScrollBarVisibility="Visible"

但内容不会横向发展。 然而,垂直滚动与往常一样可靠地运作。

如果这种投入目前得不到世界森林论坛的直接支持,那么利用不受管理的守则进行交流的方法是否可行?

感谢!

最佳回答

将“AddHook()”方法用在你的窗户中,这样你就能够传递信息。 看一看WM_MOUSEHWHEEL,电文0x20e。 Use wParam.ToInt32() >> 16 to have the movement amount, a multi of 120.

问题回答

I just made a class that adds the PreviewMouseHorizontalWheel and MouseHorizontalWheel attached events to all UIElements. These events include as parameter a MouseHorizontalWheelEventArgs HorizontalDelta.

<><>Update 3

根据WPF标准,倾斜价值被逆转,结果是积极的,下降为负值,因此留下了积极和正确的负面影响。

<><>Update 2

如果将<>AutoEnable MouseHorizontalWheelSupport定为真的(因为缺席),则没有特别要求利用这些事件。

Only if it is set to false then you will need to call either MouseHorizontalWheelEnabler.EnableMouseHorizontalWheel(X) where X is the top level element (Window, Popup or ContextMenu) or MouseHorizontalWheelEnabler.EnableMouseHorizontalWheelForParentOf(X) with the Element to enable support for. You can read the provided docs for more info on those methods.

www.un.org/Depts/DGACM/index_spanish.htm 请注意,由于WM_ MemorandumSE-H-WHEEL在Vista.上添加。

MouseHorizontalWheelEnabler.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interop;
using JetBrains.Annotations;

namespace WpfExtensions
{
    public static class MouseHorizontalWheelEnabler
    {
        /// <summary>
        ///   When true it will try to enable Horizontal Wheel support on parent windows/popups/context menus automatically
        ///   so the programmer does not need to call it.
        ///   Defaults to true.
        /// </summary>
        public static bool AutoEnableMouseHorizontalWheelSupport = true;

        private static readonly HashSet<IntPtr> _HookedWindows = new HashSet<IntPtr>();

        /// <summary>
        ///   Enable Horizontal Wheel support for all the controls inside the window.
        ///   This method does not need to be called if AutoEnableMouseHorizontalWheelSupport is true.
        ///   This does not include popups or context menus.
        ///   If it was already enabled it will do nothing.
        /// </summary>
        /// <param name="window">Window to enable support for.</param>
        public static void EnableMouseHorizontalWheelSupport([NotNull] Window window) {
            if (window == null) {
                throw new ArgumentNullException(nameof(window));
            }

            if (window.IsLoaded) {
                // handle should be available at this level
                IntPtr handle = new WindowInteropHelper(window).Handle;
                EnableMouseHorizontalWheelSupport(handle);
            }
            else {
                window.Loaded += (sender, args) => {
                    IntPtr handle = new WindowInteropHelper(window).Handle;
                    EnableMouseHorizontalWheelSupport(handle);
                };
            }
        }

        /// <summary>
        ///   Enable Horizontal Wheel support for all the controls inside the popup.
        ///   This method does not need to be called if AutoEnableMouseHorizontalWheelSupport is true.
        ///   This does not include sub-popups or context menus.
        ///   If it was already enabled it will do nothing.
        /// </summary>
        /// <param name="popup">Popup to enable support for.</param>
        public static void EnableMouseHorizontalWheelSupport([NotNull] Popup popup) {
            if (popup == null) {
                throw new ArgumentNullException(nameof(popup));
            }

            if (popup.IsOpen) {
                // handle should be available at this level
                // ReSharper disable once PossibleInvalidOperationException
                EnableMouseHorizontalWheelSupport(GetObjectParentHandle(popup.Child).Value);
            }

            // also hook for IsOpened since a new window is created each time
            popup.Opened += (sender, args) => {
                // ReSharper disable once PossibleInvalidOperationException
                EnableMouseHorizontalWheelSupport(GetObjectParentHandle(popup.Child).Value);
            };
        }

        /// <summary>
        ///   Enable Horizontal Wheel support for all the controls inside the context menu.
        ///   This method does not need to be called if AutoEnableMouseHorizontalWheelSupport is true.
        ///   This does not include popups or sub-context menus.
        ///   If it was already enabled it will do nothing.
        /// </summary>
        /// <param name="contextMenu">Context menu to enable support for.</param>
        public static void EnableMouseHorizontalWheelSupport([NotNull] ContextMenu contextMenu) {
            if (contextMenu == null) {
                throw new ArgumentNullException(nameof(contextMenu));
            }

            if (contextMenu.IsOpen) {
                // handle should be available at this level
                // ReSharper disable once PossibleInvalidOperationException
                EnableMouseHorizontalWheelSupport(GetObjectParentHandle(contextMenu).Value);
            }

            // also hook for IsOpened since a new window is created each time
            contextMenu.Opened += (sender, args) => {
                // ReSharper disable once PossibleInvalidOperationException
                EnableMouseHorizontalWheelSupport(GetObjectParentHandle(contextMenu).Value);
            };
        }

        private static IntPtr? GetObjectParentHandle([NotNull] DependencyObject depObj) {
            if (depObj == null) {
                throw new ArgumentNullException(nameof(depObj));
            }

            var presentationSource = PresentationSource.FromDependencyObject(depObj) as HwndSource;
            return presentationSource?.Handle;
        }

        /// <summary>
        ///   Enable Horizontal Wheel support for all the controls inside the HWND.
        ///   This method does not need to be called if AutoEnableMouseHorizontalWheelSupport is true.
        ///   This does not include popups or sub-context menus.
        ///   If it was already enabled it will do nothing.
        /// </summary>
        /// <param name="handle">HWND handle to enable support for.</param>
        /// <returns>True if it was enabled or already enabled, false if it couldn t be enabled.</returns>
        public static bool EnableMouseHorizontalWheelSupport(IntPtr handle) {
            if (_HookedWindows.Contains(handle)) {
                return true;
            }

            _HookedWindows.Add(handle);
            HwndSource source = HwndSource.FromHwnd(handle);
            if (source == null) {
                return false;
            }

            source.AddHook(WndProcHook);
            return true;
        }

        /// <summary>
        ///   Disable Horizontal Wheel support for all the controls inside the HWND.
        ///   This method does not need to be called in most cases.
        ///   This does not include popups or sub-context menus.
        ///   If it was already disabled it will do nothing.
        /// </summary>
        /// <param name="handle">HWND handle to disable support for.</param>
        /// <returns>True if it was disabled or already disabled, false if it couldn t be disabled.</returns>
        public static bool DisableMouseHorizontalWheelSupport(IntPtr handle) {
            if (!_HookedWindows.Contains(handle)) {
                return true;
            }

            HwndSource source = HwndSource.FromHwnd(handle);
            if (source == null) {
                return false;
            }

            source.RemoveHook(WndProcHook);
            _HookedWindows.Remove(handle);
            return true;
        }

        /// <summary>
        ///   Disable Horizontal Wheel support for all the controls inside the window.
        ///   This method does not need to be called in most cases.
        ///   This does not include popups or sub-context menus.
        ///   If it was already disabled it will do nothing.
        /// </summary>
        /// <param name="window">Window to disable support for.</param>
        /// <returns>True if it was disabled or already disabled, false if it couldn t be disabled.</returns>
        public static bool DisableMouseHorizontalWheelSupport([NotNull] Window window) {
            if (window == null) {
                throw new ArgumentNullException(nameof(window));
            }

            IntPtr handle = new WindowInteropHelper(window).Handle;
            return DisableMouseHorizontalWheelSupport(handle);
        }

        /// <summary>
        ///   Disable Horizontal Wheel support for all the controls inside the popup.
        ///   This method does not need to be called in most cases.
        ///   This does not include popups or sub-context menus.
        ///   If it was already disabled it will do nothing.
        /// </summary>
        /// <param name="popup">Popup to disable support for.</param>
        /// <returns>True if it was disabled or already disabled, false if it couldn t be disabled.</returns>
        public static bool DisableMouseHorizontalWheelSupport([NotNull] Popup popup) {
            if (popup == null) {
                throw new ArgumentNullException(nameof(popup));
            }

            IntPtr? handle = GetObjectParentHandle(popup.Child);
            if (handle == null) {
                return false;
            }

            return DisableMouseHorizontalWheelSupport(handle.Value);
        }

        /// <summary>
        ///   Disable Horizontal Wheel support for all the controls inside the context menu.
        ///   This method does not need to be called in most cases.
        ///   This does not include popups or sub-context menus.
        ///   If it was already disabled it will do nothing.
        /// </summary>
        /// <param name="contextMenu">Context menu to disable support for.</param>
        /// <returns>True if it was disabled or already disabled, false if it couldn t be disabled.</returns>
        public static bool DisableMouseHorizontalWheelSupport([NotNull] ContextMenu contextMenu) {
            if (contextMenu == null) {
                throw new ArgumentNullException(nameof(contextMenu));
            }

            IntPtr? handle = GetObjectParentHandle(contextMenu);
            if (handle == null) {
                return false;
            }

            return DisableMouseHorizontalWheelSupport(handle.Value);
        }


        /// <summary>
        ///   Enable Horizontal Wheel support for all that control and all controls hosted by the same window/popup/context menu.
        ///   This method does not need to be called if AutoEnableMouseHorizontalWheelSupport is true.
        ///   If it was already enabled it will do nothing.
        /// </summary>
        /// <param name="uiElement">UI Element to enable support for.</param>
        public static void EnableMouseHorizontalWheelSupportForParentOf(UIElement uiElement) {
            // try to add it right now
            if (uiElement is Window) {
                EnableMouseHorizontalWheelSupport((Window)uiElement);
            }
            else if (uiElement is Popup) {
                EnableMouseHorizontalWheelSupport((Popup)uiElement);
            }
            else if (uiElement is ContextMenu) {
                EnableMouseHorizontalWheelSupport((ContextMenu)uiElement);
            }
            else {
                IntPtr? parentHandle = GetObjectParentHandle(uiElement);
                if (parentHandle != null) {
                    EnableMouseHorizontalWheelSupport(parentHandle.Value);
                }

                // and in the rare case the parent window ever changes...
                PresentationSource.AddSourceChangedHandler(uiElement, PresenationSourceChangedHandler);
            }
        }

        private static void PresenationSourceChangedHandler(object sender, SourceChangedEventArgs sourceChangedEventArgs) {
            var src = sourceChangedEventArgs.NewSource as HwndSource;
            if (src != null) {
                EnableMouseHorizontalWheelSupport(src.Handle);
            }
        }

        private static void HandleMouseHorizontalWheel(IntPtr wParam) {
            int tilt = -Win32.HiWord(wParam);
            if (tilt == 0) {
                return;
            }

            IInputElement element = Mouse.DirectlyOver;
            if (element == null) {
                return;
            }

            if (!(element is UIElement)) {
                element = VisualTreeHelpers.FindAncestor<UIElement>(element as DependencyObject);
            }
            if (element == null) {
                return;
            }

            var ev = new MouseHorizontalWheelEventArgs(Mouse.PrimaryDevice, Environment.TickCount, tilt) {
                RoutedEvent = PreviewMouseHorizontalWheelEvent
                //Source = handledWindow
            };

            // first raise preview
            element.RaiseEvent(ev);
            if (ev.Handled) {
                return;
            }

            // then bubble it
            ev.RoutedEvent = MouseHorizontalWheelEvent;
            element.RaiseEvent(ev);
        }

        private static IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
            // transform horizontal mouse wheel messages 
            switch (msg) {
                case Win32.WM_MOUSEHWHEEL:
                    HandleMouseHorizontalWheel(wParam);
                    break;
            }
            return IntPtr.Zero;
        }

        private static class Win32
        {
            // ReSharper disable InconsistentNaming
            public const int WM_MOUSEHWHEEL = 0x020E;
            // ReSharper restore InconsistentNaming

            public static int GetIntUnchecked(IntPtr value) {
                return IntPtr.Size == 8 ? unchecked((int)value.ToInt64()) : value.ToInt32();
            }

            public static int HiWord(IntPtr ptr) {
                return unchecked((short)((uint)GetIntUnchecked(ptr) >> 16));
            }
        }

        #region MouseWheelHorizontal Event

        public static readonly RoutedEvent MouseHorizontalWheelEvent =
          EventManager.RegisterRoutedEvent("MouseHorizontalWheel", RoutingStrategy.Bubble, typeof(RoutedEventHandler),
            typeof(MouseHorizontalWheelEnabler));

        public static void AddMouseHorizontalWheelHandler(DependencyObject d, RoutedEventHandler handler) {
            var uie = d as UIElement;
            if (uie != null) {
                uie.AddHandler(MouseHorizontalWheelEvent, handler);

                if (AutoEnableMouseHorizontalWheelSupport) {
                    EnableMouseHorizontalWheelSupportForParentOf(uie);
                }
            }
        }

        public static void RemoveMouseHorizontalWheelHandler(DependencyObject d, RoutedEventHandler handler) {
            var uie = d as UIElement;
            uie?.RemoveHandler(MouseHorizontalWheelEvent, handler);
        }

        #endregion

        #region PreviewMouseWheelHorizontal Event

        public static readonly RoutedEvent PreviewMouseHorizontalWheelEvent =
          EventManager.RegisterRoutedEvent("PreviewMouseHorizontalWheel", RoutingStrategy.Tunnel, typeof(RoutedEventHandler),
            typeof(MouseHorizontalWheelEnabler));

        public static void AddPreviewMouseHorizontalWheelHandler(DependencyObject d, RoutedEventHandler handler) {
            var uie = d as UIElement;
            if (uie != null) {
                uie.AddHandler(PreviewMouseHorizontalWheelEvent, handler);

                if (AutoEnableMouseHorizontalWheelSupport) {
                    EnableMouseHorizontalWheelSupportForParentOf(uie);
                }
            }
        }

        public static void RemovePreviewMouseHorizontalWheelHandler(DependencyObject d, RoutedEventHandler handler) {
            var uie = d as UIElement;
            uie?.RemoveHandler(PreviewMouseHorizontalWheelEvent, handler);
        }

        #endregion
    }
}

MouseHorizontalWheelEventArgs.cs

using System.Windows.Input;

namespace WpfExtensions
{
    public class MouseHorizontalWheelEventArgs : MouseEventArgs
    {
        public int HorizontalDelta { get; }

        public MouseHorizontalWheelEventArgs(MouseDevice mouse, int timestamp, int horizontalDelta)
          : base(mouse, timestamp) {
            HorizontalDelta = horizontalDelta;
        }
    }
}

视力跟踪器。 FindAncestor的定义如下:

/// <summary>
///   Returns the first ancestor of specified type
/// </summary>
public static T FindAncestor<T>(DependencyObject current) where T : DependencyObject {
  current = GetVisualOrLogicalParent(current);

  while (current != null) {
    if (current is T) {
      return (T)current;
    }
    current = GetVisualOrLogicalParent(current);
  }

  return null;
}

private static DependencyObject GetVisualOrLogicalParent(DependencyObject obj) {
  if (obj is Visual || obj is Visual3D) {
    return VisualTreeHelper.GetParent(obj);
  }
  return LogicalTreeHelper.GetParent(obj);
}

另一种解决办法是Attaled Property。 它为任何控制而运作,这些控制可以是ScrollViewer或包含ScrollViewer。 这是一个相当简单的解决办法,最重要的是,重新使用非常容易。 我与我的项目做些什么是,将所附财产列入通用名称:/code>,ListBox,和朋友。 这样,它就永远是行之有效的。

这将与同一部的多位发展观者合作,将适用于目前已经停用在之上的每一种情况。

本文载有所附财产法典和助手类别

note: C#6 syntax

www.un.org/Depts/DGACM/index_spanish.htm 需要编码

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;

namespace MyTestProject
{
    public class TiltWheelHorizontalScroller
    {
        public static bool GetEnableTiltWheelScroll(DependencyObject obj) => (bool)obj.GetValue(EnableTiltWheelScrollProperty);
        public static void SetEnableTiltWheelScroll(DependencyObject obj, bool value) => obj.SetValue(EnableTiltWheelScrollProperty, value);

        public static readonly DependencyProperty EnableTiltWheelScrollProperty =
                DependencyProperty.RegisterAttached("EnableTiltWheelScroll", typeof(bool), typeof(TiltWheelHorizontalScroller), new UIPropertyMetadata(false, OnHorizontalMouseWheelScrollingEnabledChanged));

        static HashSet<int> controls = new HashSet<int>();
        static void OnHorizontalMouseWheelScrollingEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            Control control = d as Control;
            if (control != null && GetEnableTiltWheelScroll(d) && controls.Add(control.GetHashCode()))
            {
                control.MouseEnter += (sender, e) =>
                {
                    var scrollViewer = d.FindChildOfType<ScrollViewer>();
                    if (scrollViewer != null)
                    {
                        new TiltWheelMouseScrollHelper(scrollViewer, d);
                    }
                };
            }
        }
    }

    class TiltWheelMouseScrollHelper
    {
        /// <summary>
        /// multiplier of how far to scroll horizontally. Change as desired.
        /// </summary>
        private const int scrollFactor = 3;
        private const int WM_MOUSEHWEEL = 0x20e;
        ScrollViewer scrollViewer;
        HwndSource hwndSource;
        HwndSourceHook hook;
        static HashSet<int> scrollViewers = new HashSet<int>();

        public TiltWheelMouseScrollHelper(ScrollViewer scrollViewer, DependencyObject d)
        {
            this.scrollViewer = scrollViewer;
            hwndSource = PresentationSource.FromDependencyObject(d) as HwndSource;
            hook = WindowProc;
            hwndSource?.AddHook(hook);
            if (scrollViewers.Add(scrollViewer.GetHashCode()))
            {
                scrollViewer.MouseLeave += (sender, e) =>
                {
                    hwndSource.RemoveHook(hook);
                };
            }
        }

        IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case WM_MOUSEHWEEL:
                    Scroll(wParam);
                    handled = true;
                    break;
            }
            return IntPtr.Zero;
        }

        private void Scroll(IntPtr wParam)
        {
            int delta = (HIWORD(wParam) > 0 ? 1 : -1) * scrollFactor;
            scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + delta);
        }

        private static int HIWORD(IntPtr ptr) => (short)((((int)ptr.ToInt64()) >> 16) & 0xFFFF);
    }
}

如果你没有这样做的话,你就需要这一推广方法。

/// <summary>
/// Finds first child of provided type. If child not found, null is returned
/// </summary>
/// <typeparam name="T">Type of chiled to be found</typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static T FindChildOfType<T>(this DependencyObject originalSource) where T : DependencyObject
{
    T ret = originalSource as T;
    DependencyObject child = null;
    if (originalSource != null && ret == null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(originalSource); i++)
        {
            child = VisualTreeHelper.GetChild(originalSource, i);
            if (child != null)
            {
                if (child is T)
                {
                    ret = child as T;
                    break;
                }
                else
                {
                    ret = child.FindChildOfType<T>();
                    if (ret != null)
                    {
                        break;
                    }
                }
            }
        }
    }
    return ret;
}

<>Usage

缩略语 这里的<代码>DataItems只是测试案例的一些假数据。

<Window x:Class="MyTestProject.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:ap="clr-namespace:MyTestProject"
                Title="MainWindow" Height="350" Width="525"
                DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <DataGrid x:Name="dataGrid"
                  ItemsSource="{Binding DataItems}"
                  ap:TiltWheelHorizontalScroller.EnableTiltWheelScroll="True"/>
    </Grid>
</Window>

或者,我最后做些什么,将这种风格放在通用的xaml或你的<代码>。 适用于所有数据网的资源。 您可以将这种财产附在任何控制下<条码>。

<Style TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
    <Setter Property="ap:TiltWheelHorizontalScroller.EnableTiltWheelScroll" Value="True"/>
</Style>

This Microsoft link provides your exact requirement: horizontal scrolling

而后又凌驾于这一方法之上:

private void OnMouseTilt(int tilt)
    {
        // Write your horizontal handling codes here.
        if(!mainScrollViewer.IsVisible) return;

        if (tilt > 0)
        {
            mainScrollViewer.LineLeft();
        }
        else
        {
            mainScrollViewer.LineRight();
        }
    }




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签