Xamarin 表单切换事件导致无限循环 - 组切换

Xamarin forms switch events lead to infinte loop - Group switches

我正在尝试使用 Xamarin.Forms 开发应用程序。在某个时候,我试图将多个开关分组。这就是说,当一个开关被切换时,其他所有开关都需要取消切换,同时,至少需要有一个开关始终被切换。这就是说点击已经切换的开关不应该改变 anything.T

现在我的问题是 Xamarin.forms 开关的切换事件可以从 UI 触发,但也可以通过编程方式触发。我以为我找到了解决这个问题的方法,但仍然是这样做的: -如果开关已打开,请关闭所有其他开关并执行应用程序操作。 - 否则,如果开关已关闭,请检查是否还有其他开关打开。如果没有,请重新打开开关。如果是,什么也不做。

两个开关的示例代码可以是:

private void OnFirstToggled(object sender, EventArgs args)
{
   if(FirstSwitch.isToggled)
  {
     //Application stuff.
     SecondSwitch.isToggled = false;
  }
  else if (!SecondSwitch.isToggled)
  {
      FirstSwitch.isToggled = true;
  }
}

private void OnSecondToggled(object sender, EventArgs args)
{
   if(SecondSwitch.isToggled)
  {
     //Application stuff.
     FirstSwitch.isToggled = false;
  }
  else if (!FirstSwitch.isToggled)
  {
      SecondSwitch.isToggled = true;
  }
}

当点击已经切换的开关时,此解决方案会导致无限循环。其实就是switch的isToggled属性在true和false之间无限交替。但是,在调试时,其他事件似乎永远不会被触发(或者至少我的调试器看不到它)。这就是为什么我不明白第一次点击后 isToggled 属性 在哪里更改的原因。

我知道这可能是一个非常简单的问题,但我似乎无法在网上找到解决方案。任何人都可以看到这个问题或推荐一个更好的、通用的方法来实现这个吗?

您的问题是两个 else 块。考虑到您无论如何都要打开它。

我为您编写了一个简单的解决方案,以始终保持 Switch 组中的一个 Switch 打开。

让我们先添加三个开关进行测试,确保这些 Switch 会触发 Toggled 的相同事件:

<StackLayout>
    <!-- Place new controls here -->
    <Switch Toggled="Switch_Toggled" x:Name="FirstSwitch"/>
    <Switch Toggled="Switch_Toggled" x:Name="SecondSwitch"/>
    <Switch Toggled="Switch_Toggled" x:Name="ThirdSwitch"/>

</StackLayout>

在后面的代码中,我将这些开关添加到列表中,并在 Switch_Toggled 事件中将它们循环到 open/close 开关:

public partial class MainPage : ContentPage
{

    List<Switch> switchList;// To store all your Switches

    bool isLooping; //To make sure the Switch_Toggled metod not fired a second time during one toogle event

    public MainPage()
    {
        InitializeComponent();

        switchList = new List<Switch>();

        switchList.Add(FirstSwitch);
        switchList.Add(SecondSwitch);
        switchList.Add(ThirdSwitch);


        isLooping = false;
    }

    private void Switch_Toggled(object sender, ToggledEventArgs e)
    {
        //To make sure the Switch_Toggled metod not fired a second time during one toogle event
        if (isLooping == true)
        {
            return;
        }

        isLooping = true;

        Switch clickSwitch = sender as Switch;
        clickSwitch.IsToggled = true;

        foreach (var tempSwitch in switchList)
        {
            if (tempSwitch != clickSwitch)
            {
                if (tempSwitch.IsToggled == true)
                {
                    tempSwitch.IsToggled = false;
                }
            }
        }

        isLooping = false;
    }    
}

你可以试试这个解决方案,有什么不懂的可以随时问我。