Как сделать колесо мыши основным источником взаимодействия с пользователем в UWP? - PullRequest
0 голосов
/ 29 октября 2018

У меня есть приложение UWP с множеством кнопок, флажков и т. Д. В этом приложении я хочу сделать колесо мыши основным источником взаимодействия с пользователем. Другими словами, после запуска приложения в идеале пользователь должен иметь возможность перемещаться по элементам управления xaml (кнопкам, флажкам и т. Д.) ТОЛЬКО С ИСПОЛЬЗОВАНИЕМ КОЛЕСА МЫШИ. Как это возможно?

примечание 1: по умолчанию, когда приложение запускается, появляется курсор мыши и можно перемещаться по интерфейсу с помощью мыши. не заинтересованы в этом.

примечание 2: вкладка клавиатуры по умолчанию не работает для навигации.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

пользователь должен иметь возможность перемещаться по элементам управления 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: по умолчанию не работает вкладка клавиатуры.

Вы можете отключить навигацию по Tab в PreviewKeyDown хендере событий, которые подписаны на Window.Current.Content. Затем определите Tab нажатой клавишу set 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 , нажатые в текущем контенте.

И это пример кода , на который вы могли бы сослаться.

0 голосов
/ 29 октября 2018

Я не вижу способа, который бы не был "хаккейным", что бы я делал, я бы сделал событие, которое фиксирует щелчки левой / правой кнопкой мыши и немедленно возвращает результат.

И для каждого элемента управления, который будет недоступен для пользователя, вы можете связать команду с помощью диспетчера команд, чтобы принять только ввод средней мыши или создать событие, когда пользователь нажимает среднюю кнопку мыши.

Я буду рад создать несколько примеров, если вы что-то не поняли.

Давайте возьмем Mainwindow view и добавим событие на верхнем уровне иерархии окон

<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>
...