diff --git a/Handlers/PickerHandler.cs b/Handlers/PickerHandler.cs
index e6efa13..5958233 100644
--- a/Handlers/PickerHandler.cs
+++ b/Handlers/PickerHandler.cs
@@ -5,13 +5,13 @@ using Microsoft.Maui.Handlers;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Platform;
-using SkiaSharp;
using System.Collections.Specialized;
namespace Microsoft.Maui.Platform.Linux.Handlers;
///
/// Handler for Picker on Linux using Skia rendering.
+/// Maps IPicker interface to SkiaPicker platform view.
///
public partial class PickerHandler : ViewHandler
{
@@ -27,6 +27,7 @@ public partial class PickerHandler : ViewHandler
[nameof(IPicker.HorizontalTextAlignment)] = MapHorizontalTextAlignment,
[nameof(IPicker.VerticalTextAlignment)] = MapVerticalTextAlignment,
[nameof(IView.Background)] = MapBackground,
+ [nameof(IView.IsEnabled)] = MapIsEnabled,
[nameof(Picker.ItemsSource)] = MapItemsSource,
};
@@ -63,8 +64,17 @@ public partial class PickerHandler : ViewHandler
_itemsCollection.CollectionChanged += OnItemsCollectionChanged;
}
- // Load items
+ // Load items and sync properties
ReloadItems();
+
+ if (VirtualView != null)
+ {
+ MapTitle(this, VirtualView);
+ MapTitleColor(this, VirtualView);
+ MapTextColor(this, VirtualView);
+ MapSelectedIndex(this, VirtualView);
+ MapIsEnabled(this, VirtualView);
+ }
}
protected override void DisconnectHandler(SkiaPicker platformView)
@@ -85,11 +95,14 @@ public partial class PickerHandler : ViewHandler
ReloadItems();
}
- private void OnSelectedIndexChanged(object? sender, EventArgs e)
+ private void OnSelectedIndexChanged(object? sender, SelectedIndexChangedEventArgs e)
{
if (VirtualView is null || PlatformView is null) return;
- VirtualView.SelectedIndex = PlatformView.SelectedIndex;
+ if (VirtualView.SelectedIndex != e.NewIndex)
+ {
+ VirtualView.SelectedIndex = e.NewIndex;
+ }
}
private void ReloadItems()
@@ -111,14 +124,18 @@ public partial class PickerHandler : ViewHandler
if (handler.PlatformView is null) return;
if (picker.TitleColor is not null)
{
- handler.PlatformView.TitleColor = picker.TitleColor.ToSKColor();
+ handler.PlatformView.TitleColor = picker.TitleColor;
}
}
public static void MapSelectedIndex(PickerHandler handler, IPicker picker)
{
if (handler.PlatformView is null) return;
- handler.PlatformView.SelectedIndex = picker.SelectedIndex;
+
+ if (handler.PlatformView.SelectedIndex != picker.SelectedIndex)
+ {
+ handler.PlatformView.SelectedIndex = picker.SelectedIndex;
+ }
}
public static void MapTextColor(PickerHandler handler, IPicker picker)
@@ -126,7 +143,7 @@ public partial class PickerHandler : ViewHandler
if (handler.PlatformView is null) return;
if (picker.TextColor is not null)
{
- handler.PlatformView.TextColor = picker.TextColor.ToSKColor();
+ handler.PlatformView.TextColor = picker.TextColor;
}
}
@@ -141,7 +158,7 @@ public partial class PickerHandler : ViewHandler
}
if (font.Size > 0)
{
- handler.PlatformView.FontSize = (float)font.Size;
+ handler.PlatformView.FontSize = font.Size;
}
handler.PlatformView.Invalidate();
}
@@ -171,6 +188,13 @@ public partial class PickerHandler : ViewHandler
}
}
+ public static void MapIsEnabled(PickerHandler handler, IPicker picker)
+ {
+ if (handler.PlatformView is null) return;
+ handler.PlatformView.IsEnabled = picker.IsEnabled;
+ handler.PlatformView.Invalidate();
+ }
+
public static void MapItemsSource(PickerHandler handler, IPicker picker)
{
handler.ReloadItems();
diff --git a/Views/SkiaPicker.cs b/Views/SkiaPicker.cs
index 18b0df2..0c2b060 100644
--- a/Views/SkiaPicker.cs
+++ b/Views/SkiaPicker.cs
@@ -1,32 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
+using System.Collections.Generic;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Graphics;
using SkiaSharp;
namespace Microsoft.Maui.Platform;
///
-/// Skia-rendered picker/dropdown control with full XAML styling support.
+/// Skia-rendered picker/dropdown control with full MAUI compliance.
+/// Implements IPicker interface requirements:
+/// - Title, TitleColor for placeholder
+/// - SelectedIndex, SelectedItem for selection
+/// - TextColor, Font properties for styling
+/// - Items collection
///
public class SkiaPicker : SkiaView
{
+ #region SKColor Helper
+
+ private static SKColor ToSKColor(Color? color)
+ {
+ if (color == null) return SKColors.Transparent;
+ return new SKColor(
+ (byte)(color.Red * 255),
+ (byte)(color.Green * 255),
+ (byte)(color.Blue * 255),
+ (byte)(color.Alpha * 255));
+ }
+
+ #endregion
+
#region BindableProperties
- ///
- /// Bindable property for SelectedIndex.
- ///
public static readonly BindableProperty SelectedIndexProperty =
BindableProperty.Create(
nameof(SelectedIndex),
typeof(int),
typeof(SkiaPicker),
-1,
- BindingMode.OneWay,
- propertyChanged: (b, o, n) => ((SkiaPicker)b).OnSelectedIndexChanged());
+ BindingMode.TwoWay,
+ propertyChanged: (b, o, n) => ((SkiaPicker)b).OnSelectedIndexChanged((int)o, (int)n));
- ///
- /// Bindable property for Title.
- ///
public static readonly BindableProperty TitleProperty =
BindableProperty.Create(
nameof(Title),
@@ -36,81 +53,60 @@ public class SkiaPicker : SkiaView
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for TextColor.
- ///
public static readonly BindableProperty TextColorProperty =
BindableProperty.Create(
nameof(TextColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- SKColors.Black,
+ Colors.Black,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for TitleColor.
- ///
public static readonly BindableProperty TitleColorProperty =
BindableProperty.Create(
nameof(TitleColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- new SKColor(0x80, 0x80, 0x80),
+ Color.FromRgb(0x80, 0x80, 0x80),
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for BorderColor.
- ///
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create(
nameof(BorderColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- new SKColor(0xBD, 0xBD, 0xBD),
+ Color.FromRgb(0xBD, 0xBD, 0xBD),
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for DropdownBackgroundColor.
- ///
public static readonly BindableProperty DropdownBackgroundColorProperty =
BindableProperty.Create(
nameof(DropdownBackgroundColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- SKColors.White,
+ Colors.White,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for SelectedItemBackgroundColor.
- ///
public static readonly BindableProperty SelectedItemBackgroundColorProperty =
BindableProperty.Create(
nameof(SelectedItemBackgroundColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- new SKColor(0x21, 0x96, 0xF3, 0x30),
+ Color.FromRgba(0x21, 0x96, 0xF3, 0x30),
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for HoverItemBackgroundColor.
- ///
public static readonly BindableProperty HoverItemBackgroundColorProperty =
BindableProperty.Create(
nameof(HoverItemBackgroundColor),
- typeof(SKColor),
+ typeof(Color),
typeof(SkiaPicker),
- new SKColor(0xE0, 0xE0, 0xE0),
+ Color.FromRgb(0xE0, 0xE0, 0xE0),
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for FontFamily.
- ///
public static readonly BindableProperty FontFamilyProperty =
BindableProperty.Create(
nameof(FontFamily),
@@ -120,39 +116,30 @@ public class SkiaPicker : SkiaView
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).InvalidateMeasure());
- ///
- /// Bindable property for FontSize.
- ///
public static readonly BindableProperty FontSizeProperty =
BindableProperty.Create(
nameof(FontSize),
- typeof(float),
+ typeof(double),
typeof(SkiaPicker),
- 14f,
+ 14.0,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).InvalidateMeasure());
- ///
- /// Bindable property for ItemHeight.
- ///
public static readonly BindableProperty ItemHeightProperty =
BindableProperty.Create(
nameof(ItemHeight),
- typeof(float),
+ typeof(double),
typeof(SkiaPicker),
- 40f,
+ 40.0,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
- ///
- /// Bindable property for CornerRadius.
- ///
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create(
nameof(CornerRadius),
- typeof(float),
+ typeof(double),
typeof(SkiaPicker),
- 4f,
+ 4.0,
BindingMode.TwoWay,
propertyChanged: (b, o, n) => ((SkiaPicker)b).Invalidate());
@@ -181,54 +168,54 @@ public class SkiaPicker : SkiaView
///
/// Gets or sets the text color.
///
- public SKColor TextColor
+ public Color TextColor
{
- get => (SKColor)GetValue(TextColorProperty);
+ get => (Color)GetValue(TextColorProperty);
set => SetValue(TextColorProperty, value);
}
///
/// Gets or sets the title color.
///
- public SKColor TitleColor
+ public Color TitleColor
{
- get => (SKColor)GetValue(TitleColorProperty);
+ get => (Color)GetValue(TitleColorProperty);
set => SetValue(TitleColorProperty, value);
}
///
/// Gets or sets the border color.
///
- public SKColor BorderColor
+ public Color BorderColor
{
- get => (SKColor)GetValue(BorderColorProperty);
+ get => (Color)GetValue(BorderColorProperty);
set => SetValue(BorderColorProperty, value);
}
///
/// Gets or sets the dropdown background color.
///
- public SKColor DropdownBackgroundColor
+ public Color DropdownBackgroundColor
{
- get => (SKColor)GetValue(DropdownBackgroundColorProperty);
+ get => (Color)GetValue(DropdownBackgroundColorProperty);
set => SetValue(DropdownBackgroundColorProperty, value);
}
///
/// Gets or sets the selected item background color.
///
- public SKColor SelectedItemBackgroundColor
+ public Color SelectedItemBackgroundColor
{
- get => (SKColor)GetValue(SelectedItemBackgroundColorProperty);
+ get => (Color)GetValue(SelectedItemBackgroundColorProperty);
set => SetValue(SelectedItemBackgroundColorProperty, value);
}
///
/// Gets or sets the hover item background color.
///
- public SKColor HoverItemBackgroundColor
+ public Color HoverItemBackgroundColor
{
- get => (SKColor)GetValue(HoverItemBackgroundColorProperty);
+ get => (Color)GetValue(HoverItemBackgroundColorProperty);
set => SetValue(HoverItemBackgroundColorProperty, value);
}
@@ -244,27 +231,27 @@ public class SkiaPicker : SkiaView
///
/// Gets or sets the font size.
///
- public float FontSize
+ public double FontSize
{
- get => (float)GetValue(FontSizeProperty);
+ get => (double)GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
///
/// Gets or sets the item height.
///
- public float ItemHeight
+ public double ItemHeight
{
- get => (float)GetValue(ItemHeightProperty);
+ get => (double)GetValue(ItemHeightProperty);
set => SetValue(ItemHeightProperty, value);
}
///
/// Gets or sets the corner radius.
///
- public float CornerRadius
+ public double CornerRadius
{
- get => (float)GetValue(CornerRadiusProperty);
+ get => (double)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
@@ -304,27 +291,45 @@ public class SkiaPicker : SkiaView
#endregion
+ #region Private Fields
+
private readonly List _items = new();
private bool _isOpen;
- private float _dropdownMaxHeight = 200;
+ private double _dropdownMaxHeight = 200;
private int _hoveredItemIndex = -1;
+ #endregion
+
+ #region Events
+
///
/// Event raised when selected index changes.
///
- public event EventHandler? SelectedIndexChanged;
+ public event EventHandler? SelectedIndexChanged;
+
+ #endregion
+
+ #region Constructor
public SkiaPicker()
{
IsFocusable = true;
}
- private void OnSelectedIndexChanged()
+ #endregion
+
+ #region Event Handlers
+
+ private void OnSelectedIndexChanged(int oldValue, int newValue)
{
- SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
+ SelectedIndexChanged?.Invoke(this, new SelectedIndexChangedEventArgs(oldValue, newValue));
Invalidate();
}
+ #endregion
+
+ #region Public Methods
+
///
/// Sets the items in the picker.
///
@@ -339,10 +344,13 @@ public class SkiaPicker : SkiaView
Invalidate();
}
+ #endregion
+
+ #region Rendering
+
private void DrawDropdownOverlay(SKCanvas canvas)
{
if (_items.Count == 0 || !_isOpen) return;
- // Use ScreenBounds for overlay drawing to account for scroll offset
DrawDropdown(canvas, ScreenBounds);
}
@@ -353,21 +361,30 @@ public class SkiaPicker : SkiaView
private void DrawPickerButton(SKCanvas canvas, SKRect bounds)
{
+ var cornerRadius = (float)CornerRadius;
+ var fontSize = (float)FontSize;
+
+ // Get colors
+ var textColorSK = ToSKColor(TextColor);
+ var titleColorSK = ToSKColor(TitleColor);
+ var borderColorSK = ToSKColor(BorderColor);
+ var focusColorSK = ToSKColor(Color.FromRgb(0x21, 0x96, 0xF3));
+
// Draw background
using var bgPaint = new SKPaint
{
- Color = IsEnabled ? BackgroundColor : new SKColor(0xF5, 0xF5, 0xF5),
+ Color = IsEnabled ? BackgroundColor : ToSKColor(Color.FromRgb(0xF5, 0xF5, 0xF5)),
Style = SKPaintStyle.Fill,
IsAntialias = true
};
- var buttonRect = new SKRoundRect(bounds, CornerRadius);
+ var buttonRect = new SKRoundRect(bounds, cornerRadius);
canvas.DrawRoundRect(buttonRect, bgPaint);
// Draw border
using var borderPaint = new SKPaint
{
- Color = IsFocused ? new SKColor(0x21, 0x96, 0xF3) : BorderColor,
+ Color = IsFocused ? focusColorSK : borderColorSK,
Style = SKPaintStyle.Stroke,
StrokeWidth = IsFocused ? 2 : 1,
IsAntialias = true
@@ -375,7 +392,7 @@ public class SkiaPicker : SkiaView
canvas.DrawRoundRect(buttonRect, borderPaint);
// Draw text or title
- using var font = new SKFont(SKTypeface.Default, FontSize);
+ using var font = new SKFont(SKTypeface.Default, fontSize);
using var textPaint = new SKPaint(font)
{
IsAntialias = true
@@ -385,12 +402,12 @@ public class SkiaPicker : SkiaView
if (SelectedIndex >= 0 && SelectedIndex < _items.Count)
{
displayText = _items[SelectedIndex];
- textPaint.Color = IsEnabled ? TextColor : TextColor.WithAlpha(128);
+ textPaint.Color = IsEnabled ? textColorSK : textColorSK.WithAlpha(128);
}
else
{
displayText = Title;
- textPaint.Color = TitleColor;
+ textPaint.Color = titleColorSK;
}
var textBounds = new SKRect();
@@ -401,14 +418,14 @@ public class SkiaPicker : SkiaView
canvas.DrawText(displayText, textX, textY, textPaint);
// Draw dropdown arrow
- DrawDropdownArrow(canvas, bounds);
+ DrawDropdownArrow(canvas, bounds, textColorSK);
}
- private void DrawDropdownArrow(SKCanvas canvas, SKRect bounds)
+ private void DrawDropdownArrow(SKCanvas canvas, SKRect bounds, SKColor color)
{
using var paint = new SKPaint
{
- Color = IsEnabled ? TextColor : TextColor.WithAlpha(128),
+ Color = IsEnabled ? color : color.WithAlpha(128),
Style = SKPaintStyle.Stroke,
StrokeWidth = 2,
IsAntialias = true,
@@ -440,13 +457,25 @@ public class SkiaPicker : SkiaView
{
if (_items.Count == 0) return;
- var dropdownHeight = Math.Min(_items.Count * ItemHeight, _dropdownMaxHeight);
+ var itemHeight = (float)ItemHeight;
+ var cornerRadius = (float)CornerRadius;
+ var fontSize = (float)FontSize;
+ var dropdownMaxHeight = (float)_dropdownMaxHeight;
+
+ var dropdownHeight = Math.Min(_items.Count * itemHeight, dropdownMaxHeight);
var dropdownRect = new SKRect(
bounds.Left,
bounds.Bottom + 4,
bounds.Right,
bounds.Bottom + 4 + dropdownHeight);
+ // Get colors
+ var dropdownBgColorSK = ToSKColor(DropdownBackgroundColor);
+ var borderColorSK = ToSKColor(BorderColor);
+ var textColorSK = ToSKColor(TextColor);
+ var selectedBgColorSK = ToSKColor(SelectedItemBackgroundColor);
+ var hoverBgColorSK = ToSKColor(HoverItemBackgroundColor);
+
// Draw shadow
using var shadowPaint = new SKPaint
{
@@ -455,52 +484,52 @@ public class SkiaPicker : SkiaView
Style = SKPaintStyle.Fill
};
var shadowRect = new SKRect(dropdownRect.Left + 2, dropdownRect.Top + 2, dropdownRect.Right + 2, dropdownRect.Bottom + 2);
- canvas.DrawRoundRect(new SKRoundRect(shadowRect, CornerRadius), shadowPaint);
+ canvas.DrawRoundRect(new SKRoundRect(shadowRect, cornerRadius), shadowPaint);
// Draw dropdown background
using var bgPaint = new SKPaint
{
- Color = DropdownBackgroundColor,
+ Color = dropdownBgColorSK,
Style = SKPaintStyle.Fill,
IsAntialias = true
};
- canvas.DrawRoundRect(new SKRoundRect(dropdownRect, CornerRadius), bgPaint);
+ canvas.DrawRoundRect(new SKRoundRect(dropdownRect, cornerRadius), bgPaint);
// Draw border
using var borderPaint = new SKPaint
{
- Color = BorderColor,
+ Color = borderColorSK,
Style = SKPaintStyle.Stroke,
StrokeWidth = 1,
IsAntialias = true
};
- canvas.DrawRoundRect(new SKRoundRect(dropdownRect, CornerRadius), borderPaint);
+ canvas.DrawRoundRect(new SKRoundRect(dropdownRect, cornerRadius), borderPaint);
// Clip to dropdown bounds
canvas.Save();
- canvas.ClipRoundRect(new SKRoundRect(dropdownRect, CornerRadius));
+ canvas.ClipRoundRect(new SKRoundRect(dropdownRect, cornerRadius));
// Draw items
- using var font = new SKFont(SKTypeface.Default, FontSize);
+ using var font = new SKFont(SKTypeface.Default, fontSize);
using var textPaint = new SKPaint(font)
{
- Color = TextColor,
+ Color = textColorSK,
IsAntialias = true
};
for (int i = 0; i < _items.Count; i++)
{
- var itemTop = dropdownRect.Top + i * ItemHeight;
+ var itemTop = dropdownRect.Top + i * itemHeight;
if (itemTop > dropdownRect.Bottom) break;
- var itemRect = new SKRect(dropdownRect.Left, itemTop, dropdownRect.Right, itemTop + ItemHeight);
+ var itemRect = new SKRect(dropdownRect.Left, itemTop, dropdownRect.Right, itemTop + itemHeight);
// Draw item background
if (i == SelectedIndex)
{
using var selectedPaint = new SKPaint
{
- Color = SelectedItemBackgroundColor,
+ Color = selectedBgColorSK,
Style = SKPaintStyle.Fill
};
canvas.DrawRect(itemRect, selectedPaint);
@@ -509,7 +538,7 @@ public class SkiaPicker : SkiaView
{
using var hoverPaint = new SKPaint
{
- Color = HoverItemBackgroundColor,
+ Color = hoverBgColorSK,
Style = SKPaintStyle.Fill
};
canvas.DrawRect(itemRect, hoverPaint);
@@ -527,18 +556,23 @@ public class SkiaPicker : SkiaView
canvas.Restore();
}
+ #endregion
+
+ #region Pointer Events
+
public override void OnPointerPressed(PointerEventArgs e)
{
if (!IsEnabled) return;
+ var itemHeight = (float)ItemHeight;
+
if (IsOpen)
{
- // Use ScreenBounds for popup coordinate calculations (accounts for scroll offset)
var screenBounds = ScreenBounds;
var dropdownTop = screenBounds.Bottom + 4;
if (e.Y >= dropdownTop)
{
- var itemIndex = (int)((e.Y - dropdownTop) / ItemHeight);
+ var itemIndex = (int)((e.Y - dropdownTop) / itemHeight);
if (itemIndex >= 0 && itemIndex < _items.Count)
{
SelectedIndex = itemIndex;
@@ -551,6 +585,7 @@ public class SkiaPicker : SkiaView
IsOpen = true;
}
+ e.Handled = true;
Invalidate();
}
@@ -558,12 +593,13 @@ public class SkiaPicker : SkiaView
{
if (!_isOpen) return;
- // Use ScreenBounds for popup coordinate calculations (accounts for scroll offset)
+ var itemHeight = (float)ItemHeight;
var screenBounds = ScreenBounds;
var dropdownTop = screenBounds.Bottom + 4;
+
if (e.Y >= dropdownTop)
{
- var newHovered = (int)((e.Y - dropdownTop) / ItemHeight);
+ var newHovered = (int)((e.Y - dropdownTop) / itemHeight);
if (newHovered != _hoveredItemIndex && newHovered >= 0 && newHovered < _items.Count)
{
_hoveredItemIndex = newHovered;
@@ -586,6 +622,10 @@ public class SkiaPicker : SkiaView
Invalidate();
}
+ #endregion
+
+ #region Keyboard Events
+
public override void OnKeyDown(KeyEventArgs e)
{
if (!IsEnabled) return;
@@ -623,9 +663,29 @@ public class SkiaPicker : SkiaView
e.Handled = true;
}
break;
+
+ case Key.Home:
+ if (_items.Count > 0)
+ {
+ SelectedIndex = 0;
+ e.Handled = true;
+ }
+ break;
+
+ case Key.End:
+ if (_items.Count > 0)
+ {
+ SelectedIndex = _items.Count - 1;
+ e.Handled = true;
+ }
+ break;
}
}
+ #endregion
+
+ #region Lifecycle
+
public override void OnFocusLost()
{
base.OnFocusLost();
@@ -635,6 +695,18 @@ public class SkiaPicker : SkiaView
}
}
+ protected override void OnEnabledChanged()
+ {
+ base.OnEnabledChanged();
+ SkiaVisualStateManager.GoToState(this, IsEnabled
+ ? SkiaVisualStateManager.CommonStates.Normal
+ : SkiaVisualStateManager.CommonStates.Disabled);
+ }
+
+ #endregion
+
+ #region Layout
+
protected override SKSize MeasureOverride(SKSize availableSize)
{
return new SKSize(
@@ -642,12 +714,15 @@ public class SkiaPicker : SkiaView
40);
}
+ #endregion
+
+ #region Hit Testing
+
///
/// Override to include dropdown area in hit testing.
///
protected override bool HitTestPopupArea(float x, float y)
{
- // Use ScreenBounds for hit testing (accounts for scroll offset)
var screenBounds = ScreenBounds;
// Always include the picker button itself
@@ -657,7 +732,9 @@ public class SkiaPicker : SkiaView
// When open, also include the dropdown area
if (_isOpen && _items.Count > 0)
{
- var dropdownHeight = Math.Min(_items.Count * ItemHeight, _dropdownMaxHeight);
+ var itemHeight = (float)ItemHeight;
+ var dropdownMaxHeight = (float)_dropdownMaxHeight;
+ var dropdownHeight = Math.Min(_items.Count * itemHeight, dropdownMaxHeight);
var dropdownRect = new SKRect(
screenBounds.Left,
screenBounds.Bottom + 4,
@@ -669,4 +746,28 @@ public class SkiaPicker : SkiaView
return false;
}
+
+ #endregion
+}
+
+///
+/// Event args for selected index changed events.
+///
+public class SelectedIndexChangedEventArgs : EventArgs
+{
+ ///
+ /// Gets the old selected index.
+ ///
+ public int OldIndex { get; }
+
+ ///
+ /// Gets the new selected index.
+ ///
+ public int NewIndex { get; }
+
+ public SelectedIndexChangedEventArgs(int oldIndex, int newIndex)
+ {
+ OldIndex = oldIndex;
+ NewIndex = newIndex;
+ }
}