Обработка удержания Button C# UWP

146
06 апреля 2022, 13:50

В общем есть элемент Button и его событие Click. Нужно прибавлять к счётчику число, но т.к. это требуется делать много раз, чтобы долго не кликать, хотелось бы выполнять действие (прибавлять к счётчику) при удержании Button до отжатия. Можно ли проверить, всё ещё зажата ли кнопка или добавить событие при удержании элемента Button?

Answer 1

Т.к. в данном случае используется платформа UWP, то мы не можем использовать события MouseDown и MouseUp (там их нет). Разобравшись, я реализовал данную задачу чуть по сложнее: Воспользуемся 3-мя событиями: Click, GotFocus и PointerExited. Так же необходимо создать флаг

     private bool    clicFlag;

Сам метод обработки нажатия выглядит так:

public async void Function()
        {
            clicFlag = true;
            
            //то, что нужно выполнять при простом нажатии (клике)
            await Task.Run(async () =>
            {
                if (PointsEditor.clicFlag) Thread.Sleep(300);
                while (PointsEditor.clicFlag)
                {
                   await PointsEditor.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                           //то, что нужно выполнять при зажатии кнопки
                        });
                        Thread.Sleep(50); // можно выбрать другое значение задержки
                }
            });
        }

Так же нужен метод, переводящи фокус от кнопки на какой нибудь элемент, например TextBox:

    private void ClickHandler(TextBox textBox)
    {
        clicFlag = false;
        textBox.Focus(FocusState.Programmatic);
    }

Далее задаём события для кнопки:

    private void button_Click(object sender, RoutedEventArgs e) => ClickHandler(tBoxA);
    private void button_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) 
                                                                => ClickHandler(tBoxA);
    private void button_GotFocus(object sender, RoutedEventArgs e) => Function();
  

Основную функцию выполняет событие GotFocus, которое запускается при наведения фокуса на кнопку. Событие Click вызывается при отжатии кнопки и в данном случае оно выполняет функцию отвода фокуса, после чего метод основной завершается. При нижатии на кнопку и отводе курсора от неё (выход курсора за границы кнопки) событие клик не вызывается. Для этого необходимо собылие PointerExited.

Вот так же пример кода для нескольких кнопок.

  private bool    clicFlag;
  private void ChangeChanalValueClick(object sender, RoutedEventArgs e) => ClickHandler(tBoxA);
  private void ChangeChanalValuePointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) => ClickHandler(tBoxA);
  private void chanal_A_minus_GotFocus(object sender, RoutedEventArgs e) => control.ScrollFunction('a', -1 * programConfig.StepChangevalue);
  private void chanal_A_plus_GotFocus(object sender, RoutedEventArgs e) => control.ScrollFunction('a', programConfig.StepChangevalue);

Метод control.ScrollFunction(...) создан по подобию описанного выше метода Function(). Для каждой кнопки, для которой требуется задержка, события Click и PointerExited обрабатываются методами ChangeChanalValueClick() и ChangeChanalValuePointerExited().

Answer 2

вот пример увеличения счетчика пока кнопка зажата

public partial class Form1 : Form
    {
        private int count = 0;
        private bool _work;
        public Form1()
        {
            InitializeComponent();
        }
        // нажали и держим кнопку
        private void button2_MouseDown(object sender, MouseEventArgs e)
        {
            _work = true; // флаг при котором поток будет работать 
            Thread t = new Thread(UpdateMethod);// поток
            t.Start();// запускаем поток 
        }
        //отпустили кнопку
        private void button2_MouseUp(object sender, MouseEventArgs e)
        {
            _work = false;  // останавливаем поток
        }

        // метод 
        void UpdateMethod()
        {
            if (InvokeRequired)
            {
                while (_work)
                {
                    Invoke(new MethodInvoker(delegate
                    {
                        count++;
                        label4.Text = count.ToString();
                    }));
                }
            }
        }

    }
Answer 3

Есть такие Events как MouseDown и MouseUp - остаеться к ним привентить эйвенты и сделать поток.

https://stackoverflow.com/questions/4127270/c-sharp-how-to-loop-while-mouse-button-is-held-down

Или как в этом примере - таймер...

READ ALSO
Как изменить List<> из другого скрипта?

Как изменить List<> из другого скрипта?

В Script1 имеется список cubeList, который постоянно добавляет в себя объекты (например, по 1 кубу в секунду)

183
(C#, Unity)Как заблокировать управление?

(C#, Unity)Как заблокировать управление?

Вот у меня есть код(Без смеха):

243
Создание Control в рамках паттерна MVVM

Создание Control в рамках паттерна MVVM

Доброго времени суток!

86