【问题标题】:Xamarin.Forms.Switch sends Toggled event when value is updatedXamarin.Forms.Switch 在值更新时发送 Toggled 事件
【发布时间】:2015-10-06 17:23:24
【问题描述】:

所以我仍然以Xamarin.Forms 首次亮相。到目前为止一切顺利,如果我把我遇到的一些讨厌的错误放在一边。这是新人。如果我做错了什么,也许你们中的一个人可以告诉我。

基本上,我的界面上有一个Xamarin.Forms.Switch,我正在通过Toggled 事件监听其状态的变化。文档对此事件进行了说明:“用户切换此 Switch 时引发的事件。”

不幸的是,当我以编程方式更新开关的值时,事件会触发。

var mySwitch = new Switch ();
mySwitch.Toggled += (object sender, ToggledEventArgs e) => {
    Console.WriteLine ("Switch.Toggled event sent");
};
mySwitch.IsToggled = true;

有什么方法可以防止事件触发/知道不是用户触发了它?

【问题讨论】:

  • 它应该读起来像 SwitchCell 事件,“当开关改变值时触发”。您可以通过设置脏标志来破解它并在以编程方式更新模型时进行检查,或者从它创建一个继承的类并创建您自己的 EventHandle Delegate 将数据添加到 TEventArgs 以便接收者可以查看更改是否来自用户交互或不是
  • 您也可以在添加事件之前设置真实值 :) 或者像 @RobertN 所说的,如果需要,可以保存旧状态,或者做一些数据绑定可能更容易。
  • 开关控制是b*。事件的触发很好,因为它是切换的。它不应该在第一个数据绑定上这样做(在我看来)。我解决它的方法是在 C# 中进行数据绑定和附加事件。首先,我在开关上设置 IsToggled,然后在 IsToggledProperty 上设置绑定,然后附加事件。也许这有助于这里的其他人寻找答案。
  • 您找到解决方案了吗?我也无法弄清楚如何在第一次加载时进行数据绑定?
  • @batmaci 我没有再次使用 Xamarin.Forms,所以不,没有找到解决方案。我想我会在以编程方式更新之前取消注册 Toggled 事件。

标签: c# events xamarin xamarin.forms


【解决方案1】:

您遇到的行为是正确的:每次IsToggled 属性更改时,开关都会触发Toggled 事件。

我不确定Xamarin.Forms documentation 最近是否已更新,但截至今天它说的是Toggled 事件:

切换此 Switch 时引发的事件

示例代码

以下示例代码可防止在用户未触发 Toggled 事件时处理 Toggled 事件

using System;

using Xamarin.Forms;

namespace SwitchToggle
{
    public class SwitchPage : ContentPage
    {
        public SwitchPage()
        {
            var mySwitch = new Switch
            {
                IsToggled = true
            };
            mySwitch.Toggled += HandleSwitchToggledByUser;

            var toggleButton = new Button
            {
                Text = "Toggle The Switch"
            };
            toggleButton.Clicked += (sender, e) =>
            {
                mySwitch.Toggled -= HandleSwitchToggledByUser;
                mySwitch.IsToggled = !mySwitch.IsToggled;
                mySwitch.Toggled += HandleSwitchToggledByUser;
            };

            var mainLayout = new RelativeLayout();

            Func<RelativeLayout, double> getSwitchWidth = (parent) => parent.Measure(mainLayout.Width, mainLayout.Height).Request.Width;
            Func<RelativeLayout, double> getToggleButtonWidth = (parent) => parent.Measure(mainLayout.Width, mainLayout.Height).Request.Width;

            mainLayout.Children.Add(mySwitch,
                Constraint.RelativeToParent((parent) => parent.Width / 2 - getSwitchWidth(parent) / 2),
                Constraint.RelativeToParent((parent) => parent.Height / 2 - mySwitch.Height / 2)
            );
            mainLayout.Children.Add(toggleButton,
                Constraint.RelativeToParent((parent) => parent.Width / 2 - getToggleButtonWidth(parent) / 2),
                Constraint.RelativeToView(mySwitch, (parent, view) => view.Y + view.Height + 10)
            );

            Content = mainLayout;

        }

        async void HandleSwitchToggledByUser(object sender, ToggledEventArgs e)
        {
            await DisplayAlert(
                "Switch Toggled By User",
                "",
                "OK"
            );
        }
    }

    public class App : Application
    {
        public App()
        {
            MainPage = new NavigationPage(new SwitchPage());
        }
    }
}

【讨论】:

  • 当然,它是“准确的文档”,但是每次我想以编程方式启动开关时都必须取消注册事件仍然很痛苦。从功能的角度来看,这没有意义。
  • 哈哈,是的,这很痛苦。希望这有助于回答您的问题!让我知道我是否可以添加更多帮助!
  • 您好 Aspyct!如果您没有任何后续问题,让我们将此问题标记为已回答,以便将来有类似问题的任何人提供帮助。
  • 嗯,我想这很公平。
【解决方案2】:

每次都会调用Toggled 事件,当您手动更改切换时,也会触发Toggled 事件。

解决方案刚刚设置

mySwitch.Toggled -= HandleSwitchToggledByUser;

在您手动更改切换值之前,并编写

mySwitch.Toggled += HandleSwitchToggledByUser;

手动切换切换后,

希望对你有帮助

【讨论】:

  • 好老 Xamarin。从 Xamarin.Forms 版本 3.6.0.264807 开始,这在某种程度上不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2021-05-09
  • 2011-10-25
相关资源
最近更新 更多