Home > Software design >  How to create a function that receives as a parameter a dynamic function?
How to create a function that receives as a parameter a dynamic function?

Time:05-05

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:

  1. If I send GetCurrentDate function to this dialog box, when the action button is clicked it will get the current date.
  2. 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.

CodePudding user response:

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 null before assigning it to the Clicked event
  • Invoking an Action does 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 sender and e parameters: ShowDialogBox(context, (sender, e) => MyFunction("other data"))

CodePudding user response:

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

  • Related