I have 2 buttons on a xamarin form,
scannerButton and checkOrderButton
scannerButton opens the scanner page, scans a QRCode and populates it into a order entry field
checkOrderButton reads whatever is in the order entry field and processes validations and sends it to server for verification
what I want - is to call the checkOrderButton.Click from within the scannerButton.Click - after it has scanned the text
code:
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
};
what would be the best approach to do this?
one alternate is to dump all the functionality from checkOrderButton.Click handler into a function and then call that function from both button clicks, but I'm interested in learning how I can invoke the click event programmatically
I wrote an extension method for this purposes. This not only works in Xamarin-Forms-projects but also in WPF projects.
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
}
What I would do is having a viewmodel with a command that performs whatever logic would be done when pressing the button .
Then bind the Command property of the button to the command property in the ViewModel.
At this stage you will have a command that you can execute programmatically just as if you called "Button.Click()" if there will be such thing .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With