三态切换按钮

Three state toggle button

我一直在研究切换按钮可重复使用的控件,它有 3 种状态。但是我面临一些问题。我不确定如何继续前进并将所有人联系在一起。目前看起来我的代码没有附加到 XAML 因为点击按钮后没有任何反应?是否有任何好的类似示例可用,或者有人可以提供一些提示什么是错的?我也不知道如何将它扩展到 3 个状态...基本上我需要三个具有自己颜色的状态,如下所示:

MyCustomToggleButton.xaml:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Dash.Controls.MyCustomToggleButton">

    <Button>
      <VisualStateManager.VisualStateGroups>
        <VisualStateGroup Name="ToggleStates">
          <VisualState Name="Unactive">
            <VisualState.Setters>
              <Setter Property="Text" Value="D" />
              <Setter Property="FontSize" Value="14" />
              <Setter Property="BackgroundColor" Value="#474747" />
              <Setter Property="TextColor" Value="White" />
            </VisualState.Setters>
          </VisualState>
          <VisualState Name="Active">
            <VisualState.Setters>
              <Setter Property="Text" Value="D" />
              <Setter Property="FontSize" Value="14" />
              <Setter Property="BackgroundColor" Value="#20962d" />
              <Setter Property="TextColor" Value="White" />
            </VisualState.Setters>
          </VisualState>
          <VisualState Name="Locked">
            <VisualState.Setters>
              <Setter Property="Text" Value="D" />
              <Setter Property="FontSize" Value="14" />
              <Setter Property="BackgroundColor" Value="#FF0000" />
              <Setter Property="TextColor" Value="White" />
            </VisualState.Setters>
          </VisualState>
        </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>
    </Button>
</ContentView>

MyCustomToggleButton.xaml.cs:

  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class MyCustomToggleButton : ContentView
  {
    public event EventHandler<ToggledEventArgs> Toggled;

    public MyCustomToggleButton()
    {
      this.InitializeComponent();
    }

    public static BindableProperty IsToggledProperty =
        BindableProperty.Create(
          nameof(IsToggled), 
          typeof(bool), 
          typeof(MyCustomToggleButton), 
          false, 
          propertyChanged: OnIsToggledChanged);

    public bool IsToggled
    {
      set { SetValue(IsToggledProperty, value); }
      get { return (bool)GetValue(IsToggledProperty); }
    }

    protected override void OnParentSet()
    {
      base.OnParentSet();
      VisualStateManager.GoToState(this, "Unactive");
    }

    static async void OnIsToggledChanged(BindableObject bindable, object oldValue, object newValue)
    {
      uint delayValue = 100;

      ToggleButton toggleButton = (ToggleButton)bindable;
      bool isToggled = (bool)newValue;

      toggleButton.IsEnabled = false;
      await toggleButton.FadeTo(0.3, delayValue, Easing.Linear);

      // Fire event
      //toggleButton.Toggled?.Invoke(toggleButton, new ToggledEventArgs(isToggled));

      if (isToggled)
      {
        // Set the visual state
        VisualStateManager.GoToState(toggleButton, "Active");
      }
      else
      {
        // Set the visual state
        VisualStateManager.GoToState(toggleButton, "Unactive");
      }

      await Task.Delay((int)delayValue);

      await toggleButton.FadeTo(1, delayValue, Easing.Linear);
      toggleButton.IsEnabled = true;
    }
  }

基本上,切换按钮有三种状态:LockedActiveToggledOff。 可以将 Button 子类化,使其像 on-off 开关一样工作:点击按钮一次打开按钮,再次点击打开按钮 off.The 默认状态为 locked。请通过下面的步骤:

步骤 1:在继承自 Button 的共享项目中创建一个 ToggleButton.cs,如下所示:

    class ToggleButton : Button
{
    public event EventHandler<ToggledEventArgs> Toggled;

    public static BindableProperty IsToggledProperty =
        BindableProperty.Create("IsToggled", typeof(bool), typeof(ToggleButton), false,
                                propertyChanged: OnIsToggledChanged);

    public ToggleButton()
    {
        Clicked += (sender, args) => IsToggled ^= true;
    }

    public bool IsToggled
    {
        set { SetValue(IsToggledProperty, value); }
        get { return (bool)GetValue(IsToggledProperty); }
    }

    protected override void OnParentSet()
    {
        base.OnParentSet();
        VisualStateManager.GoToState(this, "Locked");
    }

    static void OnIsToggledChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ToggleButton toggleButton = (ToggleButton)bindable;
        bool isToggled = (bool)newValue;

        // Fire event
        toggleButton.Toggled?.Invoke(toggleButton, new ToggledEventArgs(isToggled));

        // Set the visual state
        VisualStateManager.GoToState(toggleButton, isToggled ? "Active": "ToggledOff" );
    }
}

步骤 2:创建一个 MyCustomToggleButton.xaml 内容页面并在 Xaml 中使用它,如下所示:

    <local:ToggleButton >
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="ToggleStates">
                <VisualState Name="ToggledOff">
                    <VisualState.Setters>
                        <Setter Property="Text" Value="Italic Off" />
                        <Setter Property="BackgroundColor" Value="#C0C0C0" />
                        <Setter Property="TextColor" Value="Black" />
                    </VisualState.Setters>
                </VisualState>

                <VisualState Name="Active">
                    <VisualState.Setters>
                        <Setter Property="Text" Value="D" />
                        <Setter Property="FontSize" Value="14" />
                        <Setter Property="BackgroundColor" Value="#20962d" />
                        <Setter Property="TextColor" Value="White" />
                    </VisualState.Setters>
                </VisualState>

                <VisualState Name="Locked">
                    <VisualState.Setters>
                        <Setter Property="Text" Value="D" />
                        <Setter Property="FontSize" Value="14" />
                        <Setter Property="BackgroundColor" Value="#FF0000" />
                        <Setter Property="TextColor" Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </local:ToggleButton>

MS官方参考link: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/button#creating-a-toggle-button