如何使鼠标滚轮成为UWP中用户交互的主要来源?

时间:2018-10-29 09:04:47

标签: c# xaml uwp mouseevent mousewheel

我有一个带有许多按钮,复选框等的UWP应用。在此应用中,我希望将MOUSE WHEEL用作用户交互的主要来源。换句话说,一旦应用程序运行,理想情况下,用户仅应使用鼠标轮就能浏览xaml控件(按钮,复选框等)。这怎么可能?

注释1:默认情况下,在应用运行时,会出现鼠标光标,并且可以使用鼠标在UI中进行导航。对这个不感兴趣。

注释2:默认情况下,“键盘”选项卡不起作用。

2 个答案:

答案 0 :(得分:1)

  

用户仅应使用鼠标轮才能浏览xaml控件(按钮,复选框等)。这怎么可能?

当然,您可以使用PointerWheelChanged事件来监视当前的CoreWindow鼠标滚轮。

CoreWindow.GetForCurrentThread().PointerWheelChanged += MainPage_PointerWheelChanged;

然后,您可以从MouseWheelDelta对象获得PointerPointProperties属性值。剩下的就是繁琐的计算过程。我已经通过以下代码实现了这一点。

public MainPage()
{
    this.InitializeComponent();
    CoreWindow.GetForCurrentThread().PointerWheelChanged += MainPage_PointerWheelChanged;
    this.Loaded += MainPage_Loaded;
}

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{   // RootLayout is Grid name.
    childrenCount = RootLayout.Children.Count;
}

private int childrenCount; // sub items count 
private int index; // index of focus control
private bool IsFirt = true; // first use flag
private void MainPage_PointerWheelChanged(CoreWindow sender, PointerEventArgs args)
{
    //get mouse wheel delta
    var value = args.CurrentPoint.Properties.MouseWheelDelta;

    if (IsFirt)
    {
        switch (value)
        {
            case 120:

                index = childrenCount;
                if (index == 0)
                {
                    index = childrenCount - 1;
                }
                else
                {
                    index--;
                }
                break;

            case -120:

                index = -1;

                if (index == childrenCount - 1)
                {
                    index = 0;
                }
                else
                {
                    index++;
                }
                break;

        }

        IsFirt = false;
    }
    else
    {
        switch (value)
        {
            case 120:

                if (index == 0)
                {
                    index = childrenCount - 1;
                }
                else
                {
                    index--;
                }

                break;

            case -120:

                if (index == childrenCount - 1)
                {
                    index = 0;
                }
                else
                {
                    index++;
                }

                break;
        }

    }
    // focus control with index
    var element = RootLayout.Children[index] as Control;
    element.Focus(FocusState.Keyboard);

}
  

注释2:默认情况下,“键盘”标签不起作用。

您可以在Window.Current.Content订阅的PreviewKeyDown事件暂挂器中禁用Tab导航。然后确定按下 Tab 键已设置为e.Handled = true

Window.Current.Content.PreviewKeyDown += Content_PreviewKeyDown;

private void Content_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{        
    e.Handled = e.Key == VirtualKey.Tab ? true : false;
}

上面的代码将忽略当前内容中按下的 Tab

这是您可以参考的code sample

答案 1 :(得分:0)

我看不到任何不是“ Hackey”的方法,我会创建一个事件来捕获鼠标的左/右键单击并立即返回。

对于每个用户难以使用的控件,您可以使用命令管理器绑定命令,以仅接受鼠标中键输入或在用户单击鼠标中键时创建事件。

如果您不了解某些内容,我将很乐意提供一些示例。

让我们进入主窗口视图,并在窗口层次结构的顶层添加一个事件

<Window x:Class="test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"

        <!-- This event captures every mouse down action that is clicked 
             Inside the window -->
        PreviewMouseDown="Window_PreviewMouseDown">

    <Grid>

    </Grid>
</Window>

MainWindow后面的代码

        /// <summary>
        /// This event will also capture any event, But this time you can check if the mouse button clicked is the middle mouse.           /// For now we will just return out of the method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
             // If the pressed mouse button is either the left or right button
            if(e.ChangedButton == MouseButton.Left || e.ChangedButton == MouseButton.Right)
            {
                // Exit out of the method
                return;
            };
        }

/// <summary>
        /// This event will capture every mouse down event, You can add any logic to it.
        /// For now we will just return out of the method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
    private void Button_MouseWheel(object sender, MouseButtonEventArgs e)
        {
            // If the pressed mouse button is the middle
            if(e.ChangedButton == MouseButton.Middle)
            {
                // do stuff...
            };
        }

不同的控制权

<!-- This is what you normally do -->
    <Button Click="Button_Click"/>
    <!-- Or -->
    <Button Command="{Binding MyComamnd}"/>

    <!-- This you will need to do for every interactable control -->
    <Button MouseDown="Button_MouseWheel"/>
    <!-- Or -->
    <Button>
        <!-- Bind to an MVVM input command -->
        <Button.InputBindings>
            <MouseBinding Command="{Binding MyCommand}"
                          MouseAction="MiddleClick"/>
        </Button.InputBindings>
    </Button>

制作 ScrollViewer

<ScrollViewer VerticalScrollBarVisibility="Visible">

        <!-- Use any kind of item panel here, I am using a stack panel 
             But you can also use a grid with a Grid.RowDefenition --> 
        <StackPanel>

            <Button Height="50" MouseDown="Button_MouseDown"/>
            <Button Height="50"/>
            <Button Height="50"/>
            <Button Height="50"/>
            <Button Height="50"/>

        </StackPanel>
    </ScrollViewer>