VB.net WPF :: Touchscreen не всегда запускает Click () или другие события мыши

Я изучаю проблему, из-за которой элементы управления сенсорным экраном вели себя странно на самодельной цифровой клавиатуре. Существует два варианта этой цифровой клавиатуры: один - поле пароля, другой - для обычного (видимого) цифрового ввода.

Сам проект довольно сложен, и в нем используется много разных окон.

И пароль, и числовые окна работают отлично при вызове из главного окна, однако, когда цифровая клавиатура (или поле пароля, я пробовал оба) вызывается из окон, расположенных ниже по программе, все становится немного странный.

Проблема возникает в Windows 10 (ПК для разработчиков) и Windows 7 (Активный ПК).

Описание проблемы:

При попытке нажать кнопки события нажатия кнопки не реагируют. После многократного нажатия на них, кнопки в конечном итоге начнут функционировать, как задумано. После того, как кнопки функционируют, они остаются работоспособными до закрытия окна. Нет никакой разницы из-за времени печати, движений, ...

Окно отлично работает при использовании мыши.

Мне нужно, чтобы программа работала с помощью тачпада и мыши (хотя, конечно, не одновременно).

Что я пробовал:

  • Обработка события касания в окне и использование координат положения, чтобы решить, какая кнопка была бы нажата.

Это работает, но Только для тачскрина. Кнопки по-прежнему не реагируют активно, но код события приземления функционирует должным образом.

Однако это мешает использовать мышь.

  • Обработка TouchDown и MouseLeftButtonDown через координаты положения

Отлично работает для мыши, работает для тачскрина ... пока сенсорный экран не начнет запускать дважды для каждой нажатой кнопки. Затем сенсорный экран запускает событие TouchDown, а также событие MouseLeftButtonDown. То же самое, что и раньше, как только он начинает срабатывать дважды, он продолжает срабатывать дважды.

  • Обработка MouseLeftButtonDown через координаты положения, игнорирование TouchDown

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

  • Вызов Mouse.Synchronise () в обработчике событий TouchDown или PreviewTouchDown

Я видел в этом решение похожей (но другой проблемы), но с моей стороны ничего не решило.

  • Установка e.Handled = true для пойманных обработчиков Touchdown и MouseLeftButtonDown

Такое же поведение, как и в исходном случае.

  • IsManipulationEnabled = "true" для задействованных элементов

Ничего не изменилось.

Код:

  • Дизайнер:

    <Window x:Class = "NumericKeyPad"
        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:REDACTEDNAME"
        mc:Ignorable = "d"
        Title = "NumericKeyPad" Height = "400" Width = "400">
    <DockPanel Name = "DockPanel" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" PreviewMouseLeftButtonDown = "NumericKeyPad_MouseLeftButtonDown">
       <Grid>
        <Grid HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" >
            <Grid.RowDefinitions>
                <RowDefinition Height = "10*"></RowDefinition>
                <RowDefinition Height = "10*"></RowDefinition>
                <RowDefinition Height = "10*"></RowDefinition>
                <RowDefinition Height = "10*"></RowDefinition>
                <RowDefinition Height = "10*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width = "73*"></ColumnDefinition>
                <ColumnDefinition Width = "7*"></ColumnDefinition>
                <ColumnDefinition Width = "66*"/>
                <ColumnDefinition Width = "73*"></ColumnDefinition>
                <ColumnDefinition Width = "73*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBlock Name = "Textblock" FontSize = "24" HorizontalAlignment = "Stretch" VerticalAlignment = "Center" TextWrapping = "Wrap" Text = "" Margin = "10,10,30,0" TextAlignment = "Center" Grid.ColumnSpan = "5"/>
            <Button Content = "1" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "1" Grid.Column = "0"  />
            <Button Content = "2" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "1" Grid.Column = "1"  Grid.ColumnSpan = "2"/>
            <Button Content = "3" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "1" Grid.Column = "3" />
            <Button Content = "4" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "2" Grid.Column = "0" />
            <Button Content = "5" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "2" Grid.Column = "1"  Grid.ColumnSpan = "2"/>
            <Button Content = "6" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "2" Grid.Column = "3" />
            <Button Content = "7" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "3" Grid.Column = "0" />
            <Button Content = "8" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "3" Grid.Column = "1"  Grid.ColumnSpan = "2"/>
            <Button Content = "9" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "3" Grid.Column = "3" />
            <Button Content = "0" FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "4" Grid.Column = "0"  Grid.ColumnSpan = "3"  />
            <Button Content = "," FontSize = "20" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "4" Grid.Column = "3" />
    
            <Button Content = "Back" FontSize = "16" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "1" Grid.Column = "4" Grid.RowSpan = "2" />
            <Button Content = "Enter" FontSize = "16" HorizontalAlignment = "Stretch"  Margin = "0,0,0,0" VerticalAlignment = "Stretch"  HorizontalContentAlignment = "Center" VerticalContentAlignment = "Center" Grid.Row = "3" Grid.Column = "4" Grid.RowSpan = "2" />
        </Grid>
    
    </Grid> 
    </DockPanel>
    

  • Код:

    Public Class NumericKeyPad
    Public Property NewValue As String
    
    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Try
            Dim btn As Button = CType(sender, Button)
            NewValue = NewValue + btn.Content.ToString()
            Textblock.Text = NewValue
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : Button_Click : " & ex.ToString(), "erro")
        End Try
    
    End Sub
    
    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Try
    
            Textblock.Text = NewValue
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : Window_Loaded : " & ex.ToString(), "erro")
        End Try
    End Sub
    
    Private Sub ButtonBack_Click(sender As Object, e As RoutedEventArgs)
        Try
            If (NewValue.Length > 0) Then
                NewValue = NewValue.Substring(0, NewValue.Length - 1)
                Textblock.Text = NewValue
            End If
    
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : ButtonBack_Click : " & ex.ToString(), "erro")
        End Try
    End Sub
    
    Private Sub ButtonEnter_Click(sender As Object, e As RoutedEventArgs)
        Try
            Me.Close()
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : ButtonEnter_Click : " & ex.ToString(), "erro")
        End Try
    End Sub
    
    Private Sub Textblock_IsVisibleChanged(sender As Object, e As DependencyPropertyChangedEventArgs) Handles Textblock.IsVisibleChanged
        Try
            Textblock.Text = NewValue
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : Textblock_IsVisibleChanged : " & ex.ToString(), "erro")
        End Try
    End Sub
    
    Private Sub NumericKeyPad_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Try
            Me.Focus()
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : NumericKeyPad_Loaded : " & ex.ToString(), "erro")
        End Try
    End Sub
    
    
    
    Private Sub NumericKeyPad_TouchDown(sender As Object, e As TouchEventArgs) Handles Me.TouchDown
        Try
            Dim position As Point = e.GetTouchPoint(Me.DockPanel).Position
    
            HandlePoint(position)
    
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : NumericKeyPad_TouchDown : " & ex.ToString(), "erro")
        End Try
    
    End Sub
    
    Private Sub NumericKeyPad_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
        'Try
        '    Dim position As Point = e.GetPosition(Me.DockPanel)
    
        '    HandlePoint(position)
    
        'Catch ex As Exception
        '    Worker.WriteLog("NumericKeyPad : NumericKeyPad_MouseLeftButtonDown : " & ex.ToString(), "erro")
        'End Try
    End Sub
    
    Private Sub HandlePoint(position As Point)
        Try
    
            Debug.WriteLine("position : " & position.X & " , " & position.Y)
    
            'determine where the touch event happened
    
            Dim place As String = ""
    
            Dim width As Double = Me.DockPanel.ActualWidth
            Dim height As Double = Me.DockPanel.ActualHeight
    
            'determine row
            Dim section As Double = height / 5.0
            Dim sectionCol As Double = width / 4.0
    
            Select Case True
                Case position.Y >= 0 And position.Y <= section 'Row 0
                    place = "textfield"
                Case position.Y > section And position.Y <= section * 2 '1-2-3-BACK
                    Select Case True
                        Case position.X >= 0 And position.X <= sectionCol 'Col 0
                            place = "1"
                        Case position.X > sectionCol And position.X <= sectionCol * 2 'Col 1
                            place = "2"
                        Case position.X > sectionCol * 2 And position.X <= sectionCol * 3 'Col 2
                            place = "3"
                        Case position.X > sectionCol * 3 And position.X <= sectionCol * 4 'Col 3
                            place = "bckspce"
                    End Select
    
                Case position.Y > section * 2 And position.Y <= section * 3 '4-5-6-BACK
                    Select Case True
                        Case position.X >= 0 And position.X <= sectionCol
                            place = "4"
                        Case position.X > sectionCol And position.X <= sectionCol * 2
                            place = "5"
                        Case position.X > sectionCol * 2 And position.X <= sectionCol * 3
                            place = "6"
                        Case position.X > sectionCol * 3 And position.X <= sectionCol * 4
                            place = "bckspce"
                    End Select
    
                Case position.Y > section * 3 And position.Y <= section * 4 '7-8-9-Ent
                    Select Case True
                        Case position.X >= 0 And position.X <= sectionCol
                            place = "7"
                        Case position.X > sectionCol And position.X <= sectionCol * 2
                            place = "8"
                        Case position.X > sectionCol * 2 And position.X <= sectionCol * 3
                            place = "9"
                        Case position.X > sectionCol * 3 And position.X <= sectionCol * 4
                            place = "entr"
                    End Select
    
                Case position.Y > section * 4 And position.Y <= section * 5 'NULL-cma-Ent
                    Select Case True
                        Case position.X >= 0 And position.X <= sectionCol
                            place = "0"
                        Case position.X > sectionCol And position.X <= sectionCol * 2
                            place = "0"
                        Case position.X > sectionCol * 2 And position.X <= sectionCol * 3
                            place = "cmma"
                        Case position.X > sectionCol * 3 And position.X <= sectionCol * 4
                            place = "entr"
                    End Select
            End Select
    
            Select Case place
                Case "0"
                    NewValue = NewValue + "0"
                    Textblock.Text = NewValue
                Case "1"
                    NewValue = NewValue + "1"
                    Textblock.Text = NewValue
                Case "2"
                    NewValue = NewValue + "2"
                    Textblock.Text = NewValue
                Case "3"
                    NewValue = NewValue + "3"
                    Textblock.Text = NewValue
                Case "4"
                    NewValue = NewValue + "4"
                    Textblock.Text = NewValue
                Case "5"
                    NewValue = NewValue + "5"
                    Textblock.Text = NewValue
                Case "6"
                    NewValue = NewValue + "6"
                    Textblock.Text = NewValue
                Case "7"
                    NewValue = NewValue + "7"
                    Textblock.Text = NewValue
                Case "8"
                    NewValue = NewValue + "8"
                    Textblock.Text = NewValue
                Case "9"
                    NewValue = NewValue + "9"
                    Textblock.Text = NewValue
                Case "entr"
                    Me.Close()
                Case "bckspce"
                    If (NewValue.Length > 0) Then
                        NewValue = NewValue.Substring(0, NewValue.Length - 1)
                        Textblock.Text = NewValue
                    End If
                Case "cmma"
                    NewValue = NewValue + ","
                    Textblock.Text = NewValue
                Case Else
                    'Do nothing
            End Select
        Catch ex As Exception
            Worker.WriteLog("NumericKeyPad : HandlePoint : " & ex.ToString(), "erro")
        End Try
    End Sub
    

Кто-нибудь знает, что вызывает это и как это исправить?

Заранее спасибо,

Это почти звучит так, как будто первое прикосновение просто фокусируется на окне, а следующее прикосновение выполняет щелчок. Есть ли у вас какие-либо глобальные обработчики, которые делают что-нибудь, что может мешать фокусу?

Kevin Cook 27.11.2018 14:37

@KevinCook Это то, о чем я изначально думал, однако поведение, с которым я сталкиваюсь, сохраняется, даже когда окно имеет четкий фокус. Иногда при нажатии кнопок событие касания срабатывает правильно, но кнопка не выбирается активно. Затем внезапно, даже после 15+ нажатий с разными интервалами и таймингами, кнопки начнут запускать события Click, как если бы это был щелчок мышью. При отсутствии других активных входов весь цикл может снова прерваться, из-за чего кнопки снова перестают отвечать (хотя мой обработчик Touchdown все еще улавливает их все).

Niche 27.11.2018 14:53

* Часть 2 - Мне кажется, что событие иногда обновляется до фактического события мыши, даже если событие TouchDown было установлено как e.handled = true. Читая это, я нашел тему, касающуюся Touchscreens и WPF, в которой создается впечатление, что "необработанные" сенсорные события всплывают вверх как событие мыши для обратной совместимости (что объясняет случаи, когда TouchDown и MouseLeftDown запускаются почти одновременно) . Совет состоял в том, чтобы включить IsManipulationEnabled, чтобы остановить всплытие, что ничего не изменило в моем поведении.

Niche 27.11.2018 14:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
428
0

Другие вопросы по теме