【问题标题】:Programmatically click a button in Xamarin.Forms以编程方式单击 Xamarin.Forms 中的按钮
【发布时间】:2020-02-19 18:07:04
【问题描述】:

我在 xamarin 表单上有 2 个按钮,

scannerButton 和 checkOrderButton

scannerButton 打开扫描仪页面,扫描二维码并将其填充到订单输入字段中

checkOrderButton 读取订单输入字段中的任何内容并处理验证并将其发送到服务器进行验证

我想要的 - 是在扫描仪按钮.Click 中调用 checkOrderButton.Click - 在它扫描文本之后

代码:

private async void scanCameraButton_Clicked(object sender, EventArgs e)
{
    var options = new ZXing.Mobile.MobileBarcodeScanningOptions();
    options.PossibleFormats = new List<ZXing.BarcodeFormat>() {
        ZXing.BarcodeFormat.QR_CODE,ZXing.BarcodeFormat.EAN_8, ZXing.BarcodeFormat.EAN_13
    };

    var scanPage = new ZXingScannerPage(options);
    scanPage.OnScanResult += (result) =>
    {
        //stop scan
        scanPage.IsScanning = false;

        Device.BeginInvokeOnMainThread(() =>
        {
            //pop the page and get the result
            Navigation.PopAsync();
            orderNoEntry.Text = result.Text;
        });

            //invoke checkOrderButton.Click here

    };

最好的方法是什么?

另一种方法是将 checkOrderButton.Click 处理程序中的所有功能转储到一个函数中,然后从两个按钮单击中调用该函数,但我有兴趣了解如何以编程方式调用 click 事件

【问题讨论】:

  • PerformClick 在按钮上?尽管不以编程方式单击按钮而只是调用方法会更好。
  • 不幸的是,Xamarin.Forms 按钮类缺少 RaiseEvent 或 PerformClick - 设计中注明的点, - 我在互联网上找不到如何使用 xamarin.forms 进行点击,所以我在这里发布了问题

标签: c# xamarin.forms


【解决方案1】:

我要做的是拥有一个带有命令的视图模型,该命令执行按下按钮时会执行的任何逻辑。

然后将按钮的 Command 属性绑定到 ViewModel 中的 command 属性。

在这个阶段,您将拥有一个可以以编程方式执行的命令,就像您调用“Button.Click()”一样,如果有这样的事情的话。

【讨论】:

    【解决方案2】:

    其实你应该传入两个参数,所以不应该只是Button_Click(),你应该这样调用它:Button_Click(null, null)因为它需要sender和e作为两个必填参数,看看方法定义: Button_Click(object sender, EventArgs e){..}

    【讨论】:

      【解决方案3】:

      我为此编写了一个扩展方法。这不仅适用于 Xamarin-Forms-projects,也适用于 WPF 项目。

      using System;
      using System.Reflection;
      using System.Windows;
      using System.Windows.Input;
      #if !NETSTANDARD
      using System.Windows.Controls;
      #else
      using Xamarin.Forms;
      #endif
      
      public static class ButtonExtensions
      {
          public static void PerformClick(this Button sourceButton)
          {
              // Check parameters
              if (sourceButton == null)
                  throw new ArgumentNullException(nameof(sourceButton));
      
              // 1.) Raise the Click-event
      #if !NETSTANDARD
              sourceButton.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent));
      #else
              sourceButton.RaiseEventViaReflection(nameof(sourceButton.Clicked), EventArgs.Empty);
      #endif
      
              // 2.) Execute the command, if bound and can be executed
              ICommand boundCommand = sourceButton.Command;
              if (boundCommand != null)
              {
                  object parameter = sourceButton.CommandParameter;
                  if (boundCommand.CanExecute(parameter) == true)
                      boundCommand.Execute(parameter);
              }
          }
      
      #if NETSTD
          private static void RaiseEventViaReflection<TEventArgs>(this object source, string eventName, TEventArgs eventArgs) where TEventArgs : EventArgs
          {
              var eventDelegate = (MulticastDelegate)source.GetType().GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(source);
              if (eventDelegate == null)
                  return;
              foreach (var handler in eventDelegate.GetInvocationList())
              {
      #if !(NETSTANDARD1_6 || NETSTANDARD1_5 || NETSTANDARD1_4 || NETSTANDARD1_3 || NETSTANDARD1_2 || NETSTANDARD1_1 || NETSTANDARD1_0)
                  handler.Method?.Invoke(handler.Target, new object[] { source, eventArgs });
      #else
                  handler.GetMethodInfo()?.Invoke(handler.Target, new object[] { source, eventArgs });
      #endif
              }
          }
      #endif
      }
      

      【讨论】:

        【解决方案4】:

        正如 Sami 已经提到的,我建议将 checkOrderButton.Click 的功能提取到一个单独的方法中,这样您就可以从 checkOrderButton.Click 以及 scannerButton.Click 中调用该方法。

        【讨论】:

          猜你喜欢
          • 2013-10-09
          • 2017-06-17
          • 2013-05-23
          • 1970-01-01
          • 2017-06-03
          • 1970-01-01
          • 1970-01-01
          • 2013-02-26
          • 1970-01-01
          相关资源
          最近更新 更多