Let me show you one way to do this by getting the Thumb
"HorizontalThumb" (or "VerticalThumb" if the Orientation
is Vertical
) control. You can find the Thumb
control in the DefaultSliderStyle
in the Generic.xaml file.
First, you need to install these NuGet packages:
- CommunityToolkit.WinUI.UI
We use this to get the
Thumb
control.
- CommunityToolkit.Mvvm
We use this to implement the MVVM pattern.
MainPage.xaml
<Page
x:Class="SliderExample.MainPage"
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"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid ColumnDefinitions="Auto,*">
<StackPanel
Grid.Column="0"
Orientation="Horizontal">
<Button
Command="{x:Bind ViewModel.StartIncrementingCommand}"
Content="Start timer" />
<Button
Command="{x:Bind ViewModel.StartIncrementingCancelCommand}"
Content="Stop timer" />
</StackPanel>
<Slider
x:Name="SliderControl"
Grid.Column="1"
VerticalAlignment="Center"
Maximum="100"
Minimum="0"
Value="{x:Bind ViewModel.SliderValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Page>
MainPage.xaml.cs
using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using System.Linq;
namespace SliderExample;
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
this.SliderControl.Loaded += SliderControl_Loaded;
}
public MainPageViewModel ViewModel { get; } = new();
private void SliderControl_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (this.SliderControl
.FindDescendants()
.OfType<Thumb>()
.FirstOrDefault(x => x.Name == "HorizontalThumb") is not Thumb thumb)
{
return;
}
thumb.PointerEntered += Thumb_PointerEntered;
thumb.PointerExited += Thumb_PointerExited;
}
private void Thumb_PointerExited(object sender, PointerRoutedEventArgs e)
{
ViewModel.PauseRequested = false;
}
private void Thumb_PointerEntered(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
ViewModel.PauseRequested = true;
}
}
MainPageViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace SliderExample;
public partial class MainPageViewModel : ObservableObject
{
private readonly PeriodicTimer _timer = new(TimeSpan.FromSeconds(1));
[ObservableProperty]
private double _sliderValue = 0;
[ObservableProperty]
private bool pauseRequested = false;
[RelayCommand(IncludeCancelCommand = true)]
private Task StartIncrementing(CancellationToken cancellationToken)
{
return IncrementSlider(cancellationToken);
}
private async Task IncrementSlider(CancellationToken cancellationToken)
{
try
{
while (await _timer.WaitForNextTickAsync(cancellationToken) is true)
{
if (PauseRequested is true)
{
continue;
}
SliderValue += 1;
}
}
catch (OperationCanceledException)
{
}
}
}