slidermaui

MAUI - How can slider reduction be prevented?


In my MAUI application, I am using a slider to set a timer. The user can set the desired time by sliding the slider to the appropriate position. Once the timer is started, I want to prevent the user from reducing the set time until the timer completes its countdown. This ensures that the timer runs uninterrupted for the full duration initially set by the user. How can I do this on my MAUI application?

The user should be able to increase the timer using the slider. Restriction is only to reduce the timer.

Below is the Slider code added on the XAML page:

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

Solution

  • You can create a property (e.g. public bool InputTransparent) for the view model of your current page and implement interface INotifyPropertyChanged for it. Then you can bind it to the property InputTransparent of Slider.

    I achieved the functionality on my side, you can refer to the following code:

    1.create a view model(MyViewModel.cs)

    public class MyViewModel : INotifyPropertyChanged
    {
        private bool _inputTransparent;
        public bool InputTransparent
        {
            set
            {
                SetProperty(ref _inputTransparent, value);
            }
            get { return _inputTransparent; }
        }
    
    
        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    2.On the MainPage.xaml.cs, I added a Button to start a Timer and a Label to display the value of Slider.

    MainPage.xaml

        <VerticalStackLayout
                Padding="30,0"
                Spacing="25">
    
            <Slider
             x:Name="slider"
             BackgroundColor="White"
             MinimumTrackColor="#1c98d7"
             MaximumTrackColor="#9a9a9a"
             ValueChanged="watchme_slider_ValueChanged"
                     
             Maximum="360"
             Minimum="0"
             HorizontalOptions="FillAndExpand"
                   
             InputTransparent="{Binding InputTransparent}"            
                    />
            <Label x:Name="displayLabel"
                   Text="{Binding Source={x:Reference slider},
                                  Path=Value,
                                  StringFormat='The Slider value is {0:F0}'}"
                   HorizontalOptions="Center"
                   VerticalOptions="Center" />
    
    
            <Button
                    x:Name="StartTimerBtn"
                    Text="Start Timer"
                    Clicked="OnTimerClicked"
                    HorizontalOptions="Fill" />
    
    
        </VerticalStackLayout>
    

    MainPage.xaml.cs

    public partial class MainPage : ContentPage
    {
        MyViewModel myViewModel { get; set; }
        
        //Indicates whether the value of the slider is increasing or decreasing
        bool IsIncrease = false;
    
        //Indicates whether the timer starts or ends
        bool IsTimerStart = false;
    
    
        public MainPage()
        {
            InitializeComponent();
    
            myViewModel= new MyViewModel();
            this.BindingContext = myViewModel;
    
        }
    
        private void OnTimerClicked(object sender, EventArgs e)
        {
    
            IsTimerStart = true;
    
            IDispatcherTimer timer;
    
            timer = Dispatcher.CreateTimer();
            timer.Interval = TimeSpan.FromSeconds(10);
            timer.Tick += (s, e) =>
            {
    
                myViewModel.InputTransparent = false;
    
                IsTimerStart = false;
            };
            timer.Start();
    
            //time is over
    
    
        }
    
        private void watchme_slider_ValueChanged(object sender, ValueChangedEventArgs e)
        {
    
            Slider slider = (Slider)sender;
            double value = slider.Value;
    
            IsIncrease = e.NewValue > e.OldValue;  
           
            if (IsTimerStart)
            {
    
                if (!IsIncrease)
                {
                    myViewModel.InputTransparent = true;
    
                    slider.Value = e.OldValue;
                }
            }
    
            myViewModel.InputTransparent = false;
        }
    }
    

    Note:

    1.On the event of watchme_slider_ValueChanged of Slider, I used the parameter e.NewValue and e.OldValue from ValueChangedEventArgs e to determine if the Slider is triggering an increase or a decrease event. If the reduction event is triggered, set the value of myViewModel.InputTransparent to true, and set the value of the Slider to the previous value(slider.Value = e.OldValue;), and vice versa.

    2.In fact, you can also try to use property IsEnabled to achieve this.