MAUI: как отключить DragCompletedCommand ползунка при нажатии меньшего времени

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

Но у меня есть DragCompletedCommand и в Slider, который выполняет некоторые действия. Здесь, при нажатии на нижнее время на слайдере, DragCompletedCommand также нажимал и выполнял эти действия. Как я могу это отключить?

Я попробовал, как показано ниже: добавил переменную bool в viewmodel и проверил ее значение перед выполнением действий.

public ICommand DragCompletedCommand => new Command(OnDragCompleted);

private void OnDragCompleted(object obj)
{
    if (invokeDragCompleted)
    {
        //My actions
    }
}

Я устанавливаю это значение bool из события homepage.xaml.cs страницы ValueChanged.

public void SliderValueChanged(object sender, ValueChangedEventArgs args)
{
    try
    {
        Slider slider = (Slider)sender;
        IsIncrease = args.NewValue > args.OldValue;
        if (!IsIncrease)
        {
            hpvm.InputTransparent = true;
            slider.Value = args.OldValue;
            value = args.OldValue;
            hpvm.invokeDragCompleted = false;
        }
        else
        {
            hpvm.InputTransparent = false;
            slider.Value = args.NewValue;
            value = args.NewValue;
            hpvm.invokeDragCompleted = true;
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception:>>" + ex);
    }
}

Но это событие всегда срабатывает, когда таймер работает и попеременно срабатывает блок if и else. Таким образом, значение bool становится истинным и выполняет действия над Viewmodel. Есть ли способ установить для значения bool значение false при выборе меньшего времени?

Мой код слайдера:

<Slider 
    x:Name = "watchme_slider"
    Grid.Column = "1"
    BackgroundColor = "White"
    MinimumTrackColor = "#1c98d7"
    MaximumTrackColor = "#9a9a9a"
    ThumbImageSource = "ic_thumb_xx.png"
    ValueChanged = "SliderValueChanged"
    InputTransparent = "{Binding InputTransparent}"
    Maximum = "0.166666667"
    Minimum = "0"
    DragCompletedCommand = "{Binding DragCompletedCommand}"
    HorizontalOptions = "FillAndExpand"/>

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

Обновлять

Обновлен код слайдера, как показано ниже:

<Slider 
    x:Name = "watchme_slider"
    Grid.Column = "1"
    BackgroundColor = "White"
    MinimumTrackColor = "#1c98d7"
    MaximumTrackColor = "#9a9a9a"
    ThumbImageSource = "ic_thumb_xx.png"
    ValueChanged = "SliderValueChanged"
    InputTransparent = "{Binding InputTransparent}"
    Maximum = "0.166666667"
    Minimum = "0"
    HorizontalOptions = "FillAndExpand">
    <Slider.Behaviors>
        <toolkit:EventToCommandBehavior
            EventName = "DragCompleted"
            Command = "{Binding Source = {x:Reference page}, Path=BindingContext.DragCompletedCommand}"
            CommandParameter = "{Binding Source = {x:Reference watchme_slider}}"/>
    </Slider.Behaviors>
</Slider>

Обновлен класс HomePageViewModel с ключевым словом partial:

public partial class HomePageViewModel : BaseViewModel, INotifyPropertyChanged

Комментарий ниже ICommand:

//public ICommand DragCompletedCommand => new Command(OnDragCompleted);

Добавил RelayCommand и переименовал функцию в DragCompleted:

[RelayCommand]
public void DragCompleted(object obj)
{
    var slider = obj as Slider;
    Debug.WriteLine("slider.Value:>>" + slider.Value);
    Debug.WriteLine("preValue:>>" + preValue);
    if (slider.Value > preValue)
    {
        Debug.WriteLine("do some work");
        preValue = slider.Value;
    }
}

Могу ли я спросить, какую версию .NET и платформу вы используете?

Liqun Shen-MSFT 04.07.2024 09:06

@LiqunShen-MSFT .net 8 на платформах Android и iOS

Matthew Pans 04.07.2024 09:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы устанавливаете событие slider.Value = args.OldValue; в SliderValueChanged. По этой причине срабатывают блоки if и else.

Насколько я понимаю, вы хотите совершать какие-то действия в DragCompletedCommand только тогда, когда ползунок увеличивает свое значение. Верно?

Я могу добавить новое поле, возможно, назову его preValue в ViewModel, чтобы сохранить предыдущее значение ползунка.

private double preValue;

И проверьте, больше ли текущее значение,

    [RelayCommand]
    public void DragCompleted(object obj)
    {
        var slider = obj as Slider;
        if (slider.Value > preValue)
        {
            Debug.WriteLine("do some work");
            preValue = slider.Value;
        }
    }

Вот XAML, я использую EventToCommandBehavior из Maui CommunityToolkit.

<ContentPage xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
         ...
         Title = "HomePage"
         xmlns:toolkit = "http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
         x:Name = "page">

    <Slider 
        x:Name = "watchme_slider"
        Grid.Column = "1"
        BackgroundColor = "White"
        MinimumTrackColor = "#1c98d7"
        MaximumTrackColor = "#9a9a9a"
        ThumbImageSource = "ic_thumb_xx.png"
        ValueChanged = "SliderValueChanged"
        InputTransparent = "{Binding InputTransparent}"
        Maximum = "0.166666667"
        Minimum = "0"     
        HorizontalOptions = "FillAndExpand">
        <Slider.Behaviors>
            <toolkit:EventToCommandBehavior
            EventName = "DragCompleted"
            Command = "{Binding Source = {x:Reference page}, Path=BindingContext.DragCompletedCommand}"
            CommandParameter = "{Binding Source = {x:Reference watchme_slider}}"
                />
        </Slider.Behaviors>
    </Slider>

Я попробовал это, но событие DragCompleted не запускается в первый раз.

Matthew Pans 05.07.2024 09:46

Вы имеете в виду DragCompleted событие, а не пожар? Не могли бы вы поделиться соответствующим кодом DragCompleted?

Liqun Shen-MSFT 05.07.2024 10:04

Я использую RelayCommand и EventToCommandBehavior для слайдера. Вы используете тот же код, что и мой?

Liqun Shen-MSFT 05.07.2024 10:08

В моем коде отсутствовал RelayCommand, позвольте мне попробовать еще раз

Matthew Pans 05.07.2024 10:10

Я все еще не стреляю, я обновил вопрос с учетом последних изменений, которые я внес, не могли бы вы проверить.

Matthew Pans 05.07.2024 10:23

Вы устанавливаете x:Name = "page" для ContentPage?

Liqun Shen-MSFT 05.07.2024 10:24

У меня также есть опция отмены в пользовательском интерфейсе: когда я нажимаю кнопку отмены нажатия, я устанавливаю значение ползунка на 0 следующим образом: watchme_slider.Value = 0;. Но после этой реализации он не переходит в 0, я имею в виду, что ползунок не сбрасывается.

Matthew Pans 05.07.2024 11:43

Не могли бы вы опубликовать соответствующий код для опции отмены? Насколько я понимаю, вы хотите, чтобы ползунок не уменьшал значение. Это причина, по которой сброс не работает?

Liqun Shen-MSFT 05.07.2024 11:47

При отмене просто сбрасываю время ползунка на 0, и для этого я использую этот однострочный код: watchme_slider.Value = 0;. Предотвращение уменьшения значения ползунка — это было новое требование, и оно работает сейчас. После его реализации сброс не работал.

Matthew Pans 05.07.2024 11:50

В событии SliderValueChanged, кажется, когда args.NewValue > args.OldValue;, оно установится slider.Value = args.OldValue;. Тогда я думаю, что именно поэтому он не может сбросить значение ползунка на 0.

Liqun Shen-MSFT 05.07.2024 16:12

Спасибо за причину, я исправил это с помощью одной переменной bool и Task.Delay.

Matthew Pans 08.07.2024 10:38

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