How to implement changing slider value with mouse wheel in MAUI?

175 Views Asked by At

Actually the question is in the title.
The WPF solution doesn't fit (or I haven't figured out how to adapt it), and I couldn't find anything else specific.

The solution from here also could not be adapted, because Microsoft.Maui.Platform.MauiSlider is not converted to Microsoft.Maui.Platform.ContentPanel.

2

There are 2 best solutions below

11
Liyun Zhang - MSFT On BEST ANSWER

For the windows, you can add the PointerWheelChanged event for the slider. Put the following code in the App's constructor:

        public App()
        {
            InitializeComponent();

            MainPage = new AppShell();
            Microsoft.Maui.Handlers.SliderHandler.Mapper.AppendToMapping(nameof(Slider), (handler, view) =>
            {
#if WINDOWS
                var winslider = view.Handler.PlatformView as Microsoft.UI.Xaml.Controls.Slider;
                winslider.PointerWheelChanged += (s,e) =>
                {
                    if (e.GetCurrentPoint(winslider).Properties.MouseWheelDelta>0)
                    {
                        view.Value++;
                    }
                    else
                    {
                        view.Value--;
                    }
                };
#endif
            });
        }

The slider in the xaml is: <Slider Minimum="0" Maximum="100"/>.

But I can't find a solution for the mac.

Update:

If you only want to do this for a special Slider. You can remove the code above from the App's constructor. And use it:

In the xaml :

<Slider Minimum="0" Maximum="100" x:Name="slider"/>

In the Page's OnHandlerChanged method:

protected override void OnHandlerChanged()
    {
        base.OnHandlerChanged();
#if WINDOWS
        var winslider = slider.Handler.PlatformView as Microsoft.UI.Xaml.Controls.Slider;
        winslider.PointerWheelChanged += (s,e) =>
        {
            if (e.GetCurrentPoint(winslider).Properties.MouseWheelDelta>0)
            {
                slider.Value++;
            }
            else
            {
                slider.Value--;
            }
        };
#endif
    }

This will only work for the x:Name="slider".

0
Corhal On

Based on the answer from the respected Liyun Zhang, I formed a solution for several Slider elements:

public MainPage()
{
    InitializeComponent();

    Microsoft.Maui.Handlers.SliderHandler.Mapper.AppendToMapping(nameof(Slider), (handler, view) =>
    {
#if WINDOWS
        Microsoft.UI.Xaml.Controls.Slider? winSlider = view.Handler?.PlatformView as Microsoft.UI.Xaml.Controls.Slider;

        if (winSlider != null)
        {
            winSlider.PointerWheelChanged += (s, e) =>
            {
                int step = 1;

                switch(handler)
                {
                    case slider1.Handler:
                        step = 2; //here you can replace a fixed value with a field or property
                        break;
                    case slider2.Handler;
                        step = 4; //here you can replace a fixed value with a field or property
                        break;
                }

                view.Value += e.GetCurrentPoint(winSlider).Properties.MouseWheelDelta / 120 * step;
            };
        }
#endif
    });
}

Where slider1 and slider1 elements are declared in the XAML layout as (example):

<Slider x:Name="slider1"/>
<Slider x:Name="slider2"/>