Я создаю динамическое диалоговое окно в xamarin.android
и хочу, чтобы диалоговое окно получило функцию, которую оно будет выполнять при нажатии кнопки действия.
Вот мой код:
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;
}
*Обратите внимание, что параметр Function является лишь примером. Также я сделаю текст и содержимое в этом диалоговом окне параметром.
Пример сценария:
Можно ли отправить в эту функцию ShowDialogBox
другую функцию и запускать ее при нажатии кнопки действия? Моя цель здесь — сделать мой код чистым и простым в использовании.
по моему опыту, общий диалог (или форма) — это тупиковый путь. Я имею в виду, что стоимость бизнес-уровня/UI, чтобы иметь возможность адаптироваться ко многим (разным) ситуациям, и стоимость создания нескольких компонентов в 99% случаев в пользу последних. Если вы хотите, вы можете получить некоторое преимущество с умным шаблоном композиции, но, опять же, оно того не стоит, если диалоги довольно просты.
Как уже прокомментировал @Nico, вы можете использовать Func
или делегата в качестве параметра. Вместо этого я предлагаю вам использовать Action
.
Clicked
событие на Xamarin.Forms.Button
использует обработчик событий с подписью void OnClicked(object? sender, EventArgs e)
. Поэтому в вашей подписи будет использоваться параметр Action<object?, EventArgs>
.
Несколько замечаний:
null
, прежде чем назначать его событию Clicked
Action
ничего не возвращает. Если вы хотите «получить текущую дату», ваше действие должно записать текущую дату в поле или элемент управленияsender
и e
: ShowDialogBox(context, (sender, e) => MyFunction("other data"))
Вам может помочь объектная ориентация: вы можете абстрагировать свою функцию в класс, а затем получить любой специализированный класс функции для реализации вашего конкретного действия. Что-то вроде следующего:
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();
}
Кроме того, при таком подходе очень легко добавлять новые функции: просто создайте новый класс и переопределите метод Action()
.
Другой вопрос, как я могу закрыть диалоговое окно с помощью action.Action()
?
Почему вы хотите использовать action.Action()
, чтобы закрыть диалоговое окно? В вашем коде уже есть кнопка отмены. Кроме того, для закрытия диалогового окна необходимо вызвать метод Dismiss()
. Поэтому, если вы хотите закрыть его с помощью action.Action()
, вам нужно заставить ActionClassBase получить экземпляр диалога, а затем вызвать метод Dismiss()
. @Элогист
Я хочу закрыть его после выполнения action.Action()
. Как я могу передать свое диалоговое окно в ActionClassBase
?
Вы можете попробовать код в моем ответе. @Elohist
@Elohist просто добавьте ссылку на Window
и логический флаг, чтобы решить, закрывать или нет базовый класс (устанавливайте их внутри метода ShowDialogBox
). Затем на каждом Action
вы можете решить, закрывать диалог или нет.
Вы можете создать Dialog в ActionClassBase и вызвать метод Dismiss()
в Action()
. Такие как
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();
}
}
А затем передайте диалог в ActionClassBase в файле 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);
dynamicFunction.popupDialog = popupDialog;
Вы уже изучали использование делегатов? Вы можете использовать делегат в качестве параметра, и это будет функция, которая будет выполняться динамически. Вот вопрос, на который уже ответили с тем же требованием, что и ваш вопрос. stackoverflow.com/questions/2082615/…