.net 中具有自定义外观的复选框,净MAUI

jw5wzhpr  于 2023-05-02  发布在  .NET
关注(0)|答案(2)|浏览(199)

我想使用CheckBox控件的功能,并将其外观替换为如下所示的矢量路径:

<controls:PathGeometry x:Key="IconMouseOver" Figures="M4 8v48h16v-16h16v16h16V32H20v16H4V8z M24 40V16h8v24h-8z"/>

现在,对于CheckBox的每个视觉状态(选中/未选中),结合mouseover / no mouseover,我有这样一个路径。
我尝试从CheckBox派生,但在CheckBox中找不到mouseover事件。
我能做什么?这是创建具有自定义外观的CheckBox的正确方法吗?
先谢谢你了。

qyzbxkaa

qyzbxkaa1#

我用SkiaSharp解决了。
第一步:从SKCanvasView派生一个基本控件类:

using SkiaSharp.Views.Maui;
using SkiaSharp.Views.Maui.Controls;

namespace somenamespace;

public class CustomControlBase : SKCanvasView
{
    protected bool Hover;
    protected bool Hold;

    public CustomControlBase() => EnableTouchEvents = true;

    protected override void OnTouch(SKTouchEventArgs _e)
    {
        base.OnTouch(_e);

        if (_e.ActionType == SKTouchAction.Pressed) Hold = true;
        else if (_e.ActionType == SKTouchAction.Released) Hold = false;
        else if (_e.ActionType == SKTouchAction.Entered) Hover = true;
        else if (_e.ActionType == SKTouchAction.Exited) Hover = false;

        _e.Handled = true;
    }
}

然后从它派生一个具有CheckBox功能的类:

public class CustomCheckBox : CustomControlBase
  {
        public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create(
                nameof(IsChecked), typeof(bool), typeof(CustomCheckBox), false, BindingMode.TwoWay,
                propertyChanged: OnIsCheckedChanged);
    
        public bool IsChecked
        {
            get => (bool)GetValue(IsCheckedProperty);
            set => SetValue(IsCheckedProperty, value);
        }
    
        protected override void OnTouch(SKTouchEventArgs _e)
        {
            base.OnTouch(_e);
            if (_e.ActionType == SKTouchAction.Released) IsChecked = !IsChecked;
            InvalidateSurface();
            _e.Handled = true;
        }
    
        // Here my custom appearance of the control, just for completeness
        protected override void OnPaintSurface(SKPaintSurfaceEventArgs _e)
        {
            base.OnPaintSurface(_e);
    
            Debug.WriteLine(Hold + " " + IsChecked + " " + Hover);
    
            var pathVisualization = PathVisualization.FromSymbolAndState(UiSymbol.Speaker, VisualState);
    
            var width = _e.Info.Width;
            var height = _e.Info.Height;
            float pathSize = 48;
            float padding = 0;
    
            float scaleFactor = Math.Min((width - 2 * padding) / pathSize, (height - 2 * padding) / pathSize); // Calculate the scaling factor
    
            var canvas = _e.Surface.Canvas;
            canvas.Clear(pathVisualization.BackColor.ToSKColor());
            canvas.Translate((width - pathSize * scaleFactor) / 2, (height - pathSize * scaleFactor) / 2); // Center the paths within the control
            canvas.Translate(padding, padding); // Apply padding
            canvas.Scale(scaleFactor); // Scale the paths
    
            using var paint = new SKPaint { Color = pathVisualization.ForeColor.ToSKColor(), IsAntialias = true, Style = SKPaintStyle.Fill, StrokeWidth = 1 };
            foreach (var pathString in pathVisualization.PathStrings)
            {
                using var path = SKPath.ParseSvgPathData(pathString);
                canvas.DrawPath(path, paint);
            }
        }
}
vmdwslir

vmdwslir2#

你只是想为Windows平台开发吗?Android和iOS没有鼠标,只有触摸事件。
对于windows平台,您可以将PointEntered事件添加到复选框中,当鼠标在其上时,将触发此事件。当鼠标不在PointExited事件上时,它将被触发。例如:
使用xaml中的控件:

<CheckBox x:Name="checkbox"/>

在后面的代码中:

protected override void OnHandlerChanged()
    {
            
        base.OnHandlerChanged();
#if WINDOWS
            var platformview = checkbox.Handler.PlatformView as Microsoft.UI.Xaml.Controls.CheckBox;
            platformview.PointerEntered += (s, e) =>
            {
                  // set value when mouse is over
            };
            platformview.PointerExited += (s, e) =>
            {
                  // set value when mouse is not over
            };
#endif
    }

相关问题