'How to create a function that receives as a parameter a dynamic function?
I'm creating a dynamic dialog box in xamarin.android and I want the dialog box to receive a function that it will execute upon clicking the action button.
Heres my code:
public static void ShowDialogBox(Context context, Function dynamicFunction)
{
Dialog popupDialog = new Dialog(context);
popupDialog.SetContentView(Resource.Layout.dialog_dynamic);
popupDialog.Window.SetSoftInputMode(SoftInput.AdjustResize);
popupDialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.Transparent);
popupDialog.Show();
TextView title = popupDialog.FindViewById<TextView>(Resource.Id.dialog_title);
TextView content = popupDialog.FindViewById<TextView>(Resource.Id.dialog_content);
ImageView icon = popupDialog.FindViewById<ImageView>(Resource.Id.dialog_icon);
Button actionButton = popupDialog.FindViewById<Button>(Resource.Id.dialog_action_button);
popupDialog.FindViewById<ImageButton>(Resource.Id.dialog_close).Click += delegate { popupDialog.Dismiss(); };
popupDialog.FindViewById<Button>(Resource.Id.dialog_cancel_button).Click += delegate { popupDialog.Dismiss(); };
actionButton.Click += dynamicFunction;
}
*Take note that the Function parameter is just an example. Also I will make the text and content in this dialog box a parameter.
Example scenario:
- If I send GetCurrentDate function to this dialog box, when the action button is clicked it will get the current date.
- If I send OpenBluetooth function to this dialog box, when the action button is clicked it will open the Bluetooth
It is possible to send another function to this ShowDialogBox function and run it when the action button is clicked? My purpose here it to make my code clean and easy to use.
Solution 1:[1]
Object orientation can help you: you can abstract your function into a class and then derive any specilized function class to implement your specific action. Something like the following:
abstract class ActionClassBase
{
public abstract void Action();
private string data = "";
public string Data { get { return data; } set { data = value; } }
}
class GetCurrentDateAction : ActionClassBase
{
public override void Action()
{
Data = DateTime.Now.ToString();
}
}
class OpenBlueToothAction : ActionClassBase
{
public override void Action()
{
Data = "BlueTooth opened";
}
}
public static void ShowDialogBox(Context context, ActionClassBase action)
{
Dialog popupDialog = new Dialog(context);
popupDialog.SetContentView(Resource.Layout.dialog_dynamic);
popupDialog.Window.SetSoftInputMode(SoftInput.AdjustResize);
popupDialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.Transparent);
popupDialog.Show();
TextView title = popupDialog.FindViewById<TextView>(Resource.Id.dialog_title);
TextView content = popupDialog.FindViewById<TextView>(Resource.Id.dialog_content);
ImageView icon = popupDialog.FindViewById<ImageView>(Resource.Id.dialog_icon);
Button actionButton = popupDialog.FindViewById<Button>(Resource.Id.dialog_action_button);
popupDialog.FindViewById<ImageButton>(Resource.Id.dialog_close).Click += delegate { popupDialog.Dismiss(); };
popupDialog.FindViewById<Button>(Resource.Id.dialog_cancel_button).Click += delegate { popupDialog.Dismiss(); };
actionButton.Click += (sender, ev) => action.Action();
}
Further with this approach it's very easy to add new functions: just derive a new class and override the Action() method
Solution 2:[2]
As @Nico already commented, you can use Func or a delegate as a parameter. I'd suggest you use Action instead.
The Clicked event on Xamarin.Forms.Button uses an event handler with the signature void OnClicked(object? sender, EventArgs e). Therefore, your signature would use a Action<object?, EventArgs> parameter.
A couple things to note:
- If you don't use nullable reference types in your project, omit the question marks
- You need to check the parameter for
nullbefore assigning it to theClickedevent - Invoking an
Actiondoes not return anything. If you want to "get the current date", your action must write the current date in a field or control - If your function needs other parameters, you need to pass a delegate (or wrap your function call in a function with the
senderandeparameters:ShowDialogBox(context, (sender, e) => MyFunction("other data"))
Solution 3:[3]
You can create a Dialog in the ActionClassBase and call the Dismiss() method in the Action(). Such as
abstract class ActionClassBase
{
public Dialog popupDialog;
public abstract void Action();
private string data = "";
public string Data { get { return data; } set { data = value; } }
}
class GetCurrentDateAction : ActionClassBase
{
public override void Action()
{
Data = DateTime.Now.ToString();
base.popupDialog.Dismiss();
}
}
class OpenBlueToothAction : ActionClassBase
{
public override void Action()
{
Data = "BlueTooth opened";
base.popupDialog.Dismiss();
}
}
And then, pass the dialog to the ActionClassBase in the ShowDialogBox(Context context, Function dynamicFunction) . Such as:
Dialog popupDialog = new Dialog(context);
popupDialog.SetContentView(Resource.Layout.dialog_dynamic);
popupDialog.Window.SetSoftInputMode(SoftInput.AdjustResize);
popupDialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.Transparent);
dynamicFunction.popupDialog = popupDialog;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Marco Beninca |
| Solution 2 | G_hi3 |
| Solution 3 | Liyun Zhang - MSFT |
