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.
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 theClicked
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
ande
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