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;
}
}
你可以试试这个解决方案,有什么不懂的可以随时问我。
我正在尝试使用 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;
}
}
你可以试试这个解决方案,有什么不懂的可以随时问我。