使用自定义渲染器时不会触发 Xamarin Forms Switch 的 Toggled 事件

iam*_*hia 3 xamarin xamarin.forms

我有一个Xamarin.Forms应用程序,我创建了一个自定义Switch如下:

public class ExtSwitch : Switch
{
   public static readonly BindableProperty SwitchOnColorProperty =
          BindableProperty.Create(nameof(SwitchOnColor),
                                  typeof(Color), typeof(ExtSwitch), Color.Default);

   public Color SwitchOnColor
   {
      get { return (Color)GetValue(SwitchOnColorProperty); }
      set { SetValue(SwitchOnColorProperty, value); }
   }

   // More codes here //
}
Run Code Online (Sandbox Code Playgroud)

在 MyXAML我使用它:

<local:ExtSwitch Grid.Column = "2"
       IsToggled="{Binding IsToggled}" 
       Toggled="Handle_Toggled"
       SwitchThumbColor="White" 
       SwitchOnColor="Red" 
       SwitchOffColor="Gray"
       HorizontalOptions="End" 
       VerticalOptions="Center" />
Run Code Online (Sandbox Code Playgroud)

在我的 C# 代码中,我有一个Handle_Toggled方法可以处理切换 Swich 时发生的情况。但不知何故,Toggled在我的自定义开关中使用时不会触发事件,但在普通开关中使用时效果很好。

有人可以指出我在这里缺少什么或我做错了什么吗?

编辑:

iOS 中的自定义渲染器:

class ExtSwitchRenderer : SwitchRenderer
{
   protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
   {
       base.OnElementChanged(e);

       if (e.OldElement != null || e.NewElement == null) return;

       ExtSwitch s = Element as ExtSwitch;

       UISwitch sw = new UISwitch();
       sw.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
       sw.OnTintColor = s.SwitchOnColor.ToUIColor();

       SetNativeControl(sw);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码:

在此处输入图片说明

使用下面建议的代码:

在此处输入图片说明

Android 中的自定义渲染器:

public class ExtSwitchRenderer : SwitchRenderer
    {
        public ExtSwitchRenderer(Context context) : base(context) { }
        ExtSwitch s;

       protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Switch> e)
      {
        base.OnElementChanged(e);
        if (e.OldElement != null || e.NewElement == null)
            return;

        s = Element as ExtSwitch;
        if (this.Control != null)
        {
            if (this.Control.Checked)
            {
                this.Control.TrackDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
            }
            else
            {
                this.Control.TrackDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
            }
            this.Control.CheckedChange += this.OnCheckedChange;
        }
        Control.Toggle();
    }

    void OnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
    {
        if (this.Control.Checked)
        {
            this.Control.ThumbDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.Multiply);
            this.Control.TrackDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
        }
        else
        {
            this.Control.ThumbDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.Multiply);
            this.Control.TrackDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

在 IO 渲染器上

protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
    {
        base.OnElementChanged(e);



        if (e.OldElement != null || e.NewElement == null) return;

        CustomSwitch s = Element as CustomSwitch;



        //this.Control.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
        this.Control.OnTintColor = s.SwitchOnColor.ToUIColor();

    }
Run Code Online (Sandbox Code Playgroud)

和 OnCheckedChange 中的 Android 渲染器

private void OnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
   {
        if (this.Control.Checked)
        {
            this.Control.TrackDrawable.SetColorFilter(view.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
        }
        else
        {
            this.Control.TrackDrawable.SetColorFilter(view.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
        }

        Element.IsToggled = Control.Checked;


    }
Run Code Online (Sandbox Code Playgroud)