diff --git a/src/Controls/samples/Controls.Sample/Pages/Controls/SliderPage.xaml b/src/Controls/samples/Controls.Sample/Pages/Controls/SliderPage.xaml
index da079ceaa4b8..92054c1ea705 100644
--- a/src/Controls/samples/Controls.Sample/Pages/Controls/SliderPage.xaml
+++ b/src/Controls/samples/Controls.Sample/Pages/Controls/SliderPage.xaml
@@ -43,8 +43,8 @@
-
-
+
+
diff --git a/src/Controls/samples/Controls.Sample/Resources/Images/thumb_image.svg b/src/Controls/samples/Controls.Sample/Resources/Images/thumb_image.svg
new file mode 100644
index 000000000000..800274a089d3
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample/Resources/Images/thumb_image.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/Core/src/Handlers/Slider/SliderHandler.Windows.cs b/src/Core/src/Handlers/Slider/SliderHandler.Windows.cs
index 104b8f903430..1468a86f97f8 100644
--- a/src/Core/src/Handlers/Slider/SliderHandler.Windows.cs
+++ b/src/Core/src/Handlers/Slider/SliderHandler.Windows.cs
@@ -1,4 +1,5 @@
#nullable enable
+using Microsoft.Maui.Graphics;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
@@ -8,6 +9,7 @@ namespace Microsoft.Maui.Handlers
{
public partial class SliderHandler : ViewHandler
{
+ Size? _thumbSize;
PointerEventHandler? _pointerPressedHandler;
PointerEventHandler? _pointerReleasedHandler;
@@ -45,6 +47,8 @@ protected override void DisconnectHandler(Slider platformView)
_pointerPressedHandler = null;
_pointerReleasedHandler = null;
+
+ _thumbSize = null;
}
public static void MapMinimum(ISliderHandler handler, ISlider slider)
@@ -83,7 +87,7 @@ public static void MapThumbImageSource(ISliderHandler handler, ISlider slider)
if (handler?.PlatformView is MauiSlider mauiSlider)
{
- mauiSlider.UpdateThumbImageSourceAsync(slider, provider).FireAndForget(handler);
+ mauiSlider.UpdateThumbImageSourceAsync(slider, provider, (handler as SliderHandler)?._thumbSize).FireAndForget(handler);
}
}
@@ -91,8 +95,15 @@ void OnPlatformViewLoaded(object sender, RoutedEventArgs e)
{
var platformView = sender as Slider;
- if (platformView != null)
+ if (platformView is not null)
+ {
+ var thumb = platformView.GetFirstDescendant();
+
+ if (thumb is not null)
+ _thumbSize = new Size(thumb.Width, thumb.Height);
+
platformView.ValueChanged += OnPlatformValueChanged;
+ }
}
void OnPlatformValueChanged(object? sender, RangeBaseValueChangedEventArgs e)
diff --git a/src/Core/src/Platform/Windows/SliderExtensions.cs b/src/Core/src/Platform/Windows/SliderExtensions.cs
index 356e748a2c89..d9922b323978 100644
--- a/src/Core/src/Platform/Windows/SliderExtensions.cs
+++ b/src/Core/src/Platform/Windows/SliderExtensions.cs
@@ -1,7 +1,11 @@
#nullable enable
using System;
using System.Threading.Tasks;
+using Microsoft.Maui.Graphics;
+using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Controls.Primitives;
+using Microsoft.UI.Xaml.Media.Imaging;
namespace Microsoft.Maui.Platform
{
@@ -99,13 +103,22 @@ public static void UpdateThumbColor(this Slider platformSlider, ISlider slider)
"SliderThumbBackgroundDisabled",
};
- internal static async Task UpdateThumbImageSourceAsync(this MauiSlider nativeSlider, ISlider slider, IImageSourceServiceProvider? provider)
+ internal static async Task UpdateThumbImageSourceAsync(this MauiSlider nativeSlider, ISlider slider, IImageSourceServiceProvider? provider, Size? defaultThumbSize)
{
var thumbImageSource = slider.ThumbImageSource;
if (thumbImageSource == null)
{
nativeSlider.ThumbImageSource = null;
+
+ var thumb = nativeSlider.GetFirstDescendant();
+
+ if (defaultThumbSize.HasValue && thumb is not null)
+ {
+ thumb.Height = defaultThumbSize.Value.Height;
+ thumb.Width = defaultThumbSize.Value.Width;
+ }
+
return;
}
@@ -113,7 +126,29 @@ internal static async Task UpdateThumbImageSourceAsync(this MauiSlider nativeSli
{
var service = provider.GetRequiredImageSourceService(thumbImageSource);
var nativeThumbImageSource = await service.GetImageSourceAsync(thumbImageSource);
-
+ var nativeThumbImage = nativeThumbImageSource?.Value;
+
+ // BitmapImage is a special case that has an event when the image is loaded
+ // when this happens, we want to resize the thumb
+ if (nativeThumbImage is BitmapImage bitmapImage)
+ {
+ bitmapImage.ImageOpened += OnImageOpened;
+
+ void OnImageOpened(object sender, RoutedEventArgs e)
+ {
+ bitmapImage.ImageOpened -= OnImageOpened;
+
+ if (nativeSlider.TryGetFirstDescendant(out var thumb))
+ {
+ thumb.Height = bitmapImage.PixelHeight;
+ thumb.Width = bitmapImage.PixelWidth;
+ }
+
+ if (nativeSlider.Parent is FrameworkElement frameworkElement)
+ frameworkElement.InvalidateMeasure();
+ };
+ }
+
nativeSlider.ThumbImageSource = nativeThumbImageSource?.Value;
}
}
diff --git a/src/Core/tests/DeviceTests/Handlers/Slider/SliderHandlerTests.Windows.cs b/src/Core/tests/DeviceTests/Handlers/Slider/SliderHandlerTests.Windows.cs
index 2def3b26c5c0..a79077fce128 100644
--- a/src/Core/tests/DeviceTests/Handlers/Slider/SliderHandlerTests.Windows.cs
+++ b/src/Core/tests/DeviceTests/Handlers/Slider/SliderHandlerTests.Windows.cs
@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.UI.Xaml.Controls;
+using Microsoft.UI.Xaml.Controls.Primitives;
using Xunit;
namespace Microsoft.Maui.DeviceTests
@@ -35,6 +36,69 @@ public async Task SmallChangeInitializesCorrectly(double min, double max, double
Assert.True(expected != 0);
}
+ [Fact]
+ public async Task ThumbImageSourceUpdatesCorrectly()
+ {
+ var slider = new SliderStub
+ {
+ Maximum = 10,
+ Minimum = 0,
+ Value = 5,
+ ThumbImageSource = new FileImageSourceStub("black.png"),
+ };
+
+ // Update the Slider ThumbImageSource
+ slider.ThumbImageSource = new FileImageSourceStub("red.png");
+
+ await InvokeOnMainThreadAsync(async () =>
+ {
+ var handler = CreateHandler(slider);
+
+ bool imageLoaded = await Wait(() => ImageSourceLoaded(handler));
+
+ Assert.True(imageLoaded);
+
+ await Task.Delay(100);
+
+ var expectedColor = Color.FromArgb("#FF0000");
+ await handler.PlatformView.AssertContainsColor(expectedColor);
+ });
+ }
+
+ [Theory]
+ [InlineData("red.png", 100, 100)]
+ [InlineData("black.png", 100, 100)]
+ public async Task ThumbImageSourceSizeIsCorrect(string filename, double thumbHeight, double thumbWidth)
+ {
+ var slider = new SliderStub
+ {
+ Maximum = 10,
+ Minimum = 0,
+ Value = 5,
+ ThumbImageSource = new FileImageSourceStub("black.png"),
+ };
+
+ await InvokeOnMainThreadAsync(async () =>
+ {
+ var handler = CreateHandler(slider);
+
+ bool imageLoaded = await Wait(() => ImageSourceLoaded(handler));
+ Assert.True(imageLoaded);
+
+ await handler.PlatformView.AttachAndRun(async () =>
+ {
+ // Update the Slider ThumbImageSource
+ slider.ThumbImageSource = new FileImageSourceStub(filename);
+
+ await Task.Delay(100);
+
+ var nativeThumbSize = GetNativeThumbSize(handler);
+ Assert.Equal(nativeThumbSize.Height, thumbHeight);
+ Assert.Equal(nativeThumbSize.Width, thumbWidth);
+ });
+ });
+ }
+
Slider GetNativeSlider(SliderHandler sliderHandler) =>
sliderHandler.PlatformView;
@@ -48,6 +112,23 @@ double GetNativeMaximum(SliderHandler sliderHandler) =>
GetNativeSlider(sliderHandler).Maximum;
double GetSmallChange(SliderHandler sliderHandler) =>
- GetNativeSlider(sliderHandler).SmallChange;
+ GetNativeSlider(sliderHandler).SmallChange;
+
+ Size GetNativeThumbSize(SliderHandler sliderHandler)
+ {
+ var nativeSlider = GetNativeSlider(sliderHandler);
+
+ if(nativeSlider.GetFirstDescendant() is Thumb thumb)
+ {
+ return new Size(thumb.Width, thumb.Height);
+ }
+
+ return Size.Zero;
+ }
+
+ bool ImageSourceLoaded(SliderHandler sliderHandler)
+ {
+ return (sliderHandler.PlatformView as MauiSlider)?.ThumbImageSource != null;
+ }
}
}
\ No newline at end of file