IChoiceDialogService¶
IChoiceDialogService предоставляет платформенно-независимый способ показать модальный диалог с произвольным набором кнопок и вернуть результат нажатой кнопки. Результатом диалога может быть string, bool, значение перечисления или любой другой тип. С помощью IChoiceDialogService ViewModel может отобразить диалог и получить строго типизированный ответ, не ссылаясь ни на какой тип окна.
Основные возможности:
- Диалог автоматически закрывается при нажатии одной из его кнопок выбора (расположенных в нижней части диалога).
- Любое количество кнопок выбора — Для каждой кнопки можно задать подпись и связать её с результатом диалога, который возвращается при нажатии этой кнопки.
- Результат диалога — Результат диалога определяется значением
Resultнажатой кнопки, которое может бытьstring,bool, перечислением или любым другим типом. - Настраиваемое расположение кнопок — Кнопки диалога поддерживают свойство
Dock, которое позволяет принудительно разместить кнопки первыми или последними. - Кнопка по умолчанию — Любую кнопку можно отметить как кнопку по умолчанию. Когда пользователь нажимает ENTER, диалог вызывает команду этой кнопки.
- Кнопка отмены — Отметьте любую кнопку с помощью
IsCancel, чтобы она реагировала на ESC. - Автоматический владелец — Окно-владелец определяется базовым сервисом
IDialogServiceчерезIWindowsManager, поэтому его не нужно задавать явно. - Кнопки выбора всегда доступны — В отличие от IDialogService, который поддерживает
CanOkдля валидации, вIChoiceDialogServiceнет механизма, позволяющего отключать отдельные варианты выбора в зависимости от состояния ввода.
Определение интерфейса¶
public interface IChoiceDialogService
{
// Show a modal dialog with the given choices.
T Show<T>(string message, string? caption, IReadOnlyList<DialogChoice<T>> choices);
}
| Параметр | Тип | Описание |
|---|---|---|
message |
string |
Основное содержимое диалога, присваиваемое свойству Content ViewModel диалога. Не может быть null. |
caption |
string? |
Заголовок диалога. Если задано значение null, заголовок берётся из свойства Title ViewModel диалога. |
choices |
IReadOnlyList<DialogChoice<T>> |
Доступные варианты выбора, отображаемые в виде кнопок в нижней части диалога. Порядок соответствует порядку кнопок. Не может быть null и должен содержать хотя бы один элемент. |
Возвращаемое значение:
T— результат, связанный с нажатой кнопкой выбораdefault(T), если диалог был закрыт без выбора нажатием кнопки закрытия ('x') диалога.default(T)равноnullдля ссылочных типов (включаяstring),falseдля типаbool,0для перечисления без явного нулевого члена.- Нажатие ENTER — Если в диалоге есть кнопка выбора с
IsDefault = true, нажатие ENTER возвращает значениеResultэтой кнопки. Если ни у одной кнопки выбора нетIsDefault = true, нажатие ENTER ничего не делает, и диалог остаётся открытым. - Нажатие ESC — Если в диалоге есть кнопка выбора с
IsCancel = true, нажатие Escape возвращает значениеResultэтой кнопки. Если ни у одной кнопки выбора нетIsCancel = true, нажатие Escape ничего не делает, и диалог остаётся открытым.
См. также: Обработка закрытия диалога без выбора.
Исключения:
ArgumentNullException— Параметрmessageилиchoicesравенnull.ArgumentException— Списокchoicesпуст. Диалог должен содержать хотя бы одну кнопку.
DialogChoice¶
Каждая кнопка выбора в диалоге описывается экземпляром DialogChoice<T>:
public sealed class DialogChoice<T>
{
// The button caption.
public string Caption { get; }
// The result returned by the `IChoiceDialogService.Show` method when the button is pressed.
public T Result { get; }
// Whether the current button is the default button, invoked by Enter.
public bool IsDefault { get; set; }
// Whether the current button is the cancel button, invoked by Escape.
public bool IsCancel { get; set; }
// The side to which the button is docked. Defaults to `DockType.Right`.
public DockType Dock { get; set; } = DockType.Right;
// The button order within its side. Use the `Index` property when you need to reorder buttons without changing the button array.
public int? Index { get; set; }
public DialogChoice(string caption, T result);
}
Как использовать IChoiceDialogService¶
В ViewModel вызовите метод IChoiceDialogService.Show, чтобы отобразить диалог с указанными кнопками выбора. Метод возвращает значение Result нажатой кнопки выбора.
Доступ к сервису¶
Получить объект IChoiceDialogService в ViewModel можно двумя способами:
- С помощью вспомогательного метода
Service<T>(). Это удобный способ получить зарегистрированные сервисы приложения, входящие в библиотеку Eremex Controls. - Через внедрение в конструктор.
Вспомогательный метод Service()¶
Реализуйте в ViewModel вспомогательный метод Service<T>(), который получает запрошенный сервис с помощью статического метода ApplicationServicesContext.GetRequiredService<T>().
Пример - отображение диалога с помощью вспомогательного метода Service()¶
using Eremex.AvaloniaUI.Controls.ApplicationServices;
using CommunityToolkit.Mvvm.Input;
public partial class MyViewModel : ObservableObject
{
// Provides access to any registered service
protected static T Service<T>() where T : class
=> ApplicationServicesContext.GetRequiredService<T>();
[RelayCommand]
private void ShowChoiceDialog()
{
// Resolve the service and show the dialog
var result = Service<IChoiceDialogService>().Show(
"The license server did not respond.",
"Activation failed",
new[]
{
new DialogChoice<string>("Show log", "log") { IsDefault = true },
new DialogChoice<string>("Retry", "retry"),
new DialogChoice<string>("Close", "close") { IsCancel = true },
});
if(result == "retry")
{
//...
}
else
{
//...
}
}
}
Убедитесь, что в файле App.axaml.cs сервисы приложения Eremex зарегистрированы с помощью SimpleServiceProvider и ApplicationServicesContext следующим образом:
public class App : Application
{
public override void OnFrameworkInitializationCompleted()
{
RegisterApplicationServices();
//...
}
static void RegisterApplicationServices()
{
// Register built-in services.
var serviceProvider = new SimpleServiceProvider();
ApplicationServicesContext.RegisterApplicationServices(serviceProvider.AddSingleton);
ApplicationServicesContext.SetCurrent(serviceProvider);
}
}
Внедрение в конструктор¶
Реализуйте в ViewModel конструктор с параметром типа IChoiceDialogService. При создании ViewModel передайте объект сервиса в этот конструктор.
public partial class MyViewModel
{
private readonly IChoiceDialogService _choiceDialogService;
public MyViewModel(IChoiceDialogService choiceDialogService)
{
_choiceDialogService = choiceDialogService;
}
[RelayCommand]
private void ShowChoiceDialog()
{
var result = _choiceDialogService.Show(
"The license server did not respond.",
"Activation failed",
new[]
{
new DialogChoice<string>("Show log", "log") { IsDefault = true },
new DialogChoice<string>("Retry", "retry"),
new DialogChoice<string>("Close", "close") { IsCancel = true },
});
//...
}
}
Возврат строкового результата¶
Чтобы при нажатии кнопки диалога возвращалось строковое значение, используйте для этой кнопки DialogChoice<string>. Значение, связанное с кнопкой, задаётся параметром result конструктора DialogChoice<T>.
В этом примере показан диалог с тремя кнопками. С этими кнопками связаны определённые результаты диалога (строковые значения "log", "retry" и "close"). Метод Show диалога возвращает соответствующее значение при нажатии одной из его кнопок.
[RelayCommand]
private void ShowDialogWithCustomCaptions()
{
var result = Service<IChoiceDialogService>().Show(
DialogMessage,
DialogTitle,
new[]
{
new DialogChoice<string>("Show log", "log") { IsDefault = true },
new DialogChoice<string>("Retry", "retry"),
new DialogChoice<string>("Close", "close") { IsCancel = true },
});
}
Возврат логического результата¶
Чтобы при нажатии кнопки диалога возвращалось логическое значение, используйте для этой кнопки DialogChoice<bool>. Значение, связанное с кнопкой, задаётся параметром result конструктора DialogChoice<T>.
В этом примере показан диалог с двумя кнопками. С этими кнопками связаны определённые результаты диалога (true и false). Метод Show диалога возвращает соответствующее значение при нажатии одной из его кнопок.
[RelayCommand]
private void ShowDialogWithBooleanResult()
{
var result = Service<IChoiceDialogService>().Show(
DialogMessage,
DialogTitle,
new[]
{
new DialogChoice<bool>("Show log", true) { IsDefault = true },
new DialogChoice<bool>("Close", false) { IsCancel = true },
});
}
См. также: Обработка закрытия диалога без выбора.
Возврат значения перечисления¶
Чтобы при нажатии кнопки диалога возвращалось значение перечисления, используйте для этой кнопки DialogChoice< enum >. Значение, связанное с кнопкой, задаётся параметром result конструктора DialogChoice<T>.
В этом примере показан диалог с тремя кнопками. С этими кнопками связаны определённые результаты диалога (DialogResult.Abort, DialogResult.Retry и DialogResult.Ignore). Метод Show диалога возвращает соответствующее значение при нажатии одной из его кнопок.
[RelayCommand]
private void ShowDialogWithEnumResult()
{
var result = Service<IChoiceDialogService>().Show(
DialogMessage,
DialogTitle,
new[]
{
new DialogChoice<DialogResult>("Abort", DialogResult.Abort) { IsCancel = true },
new DialogChoice<DialogResult>("Retry", DialogResult.Retry) { IsDefault = true },
new DialogChoice<DialogResult>("Ignore", DialogResult.Ignore),
});
}
Расположение кнопок¶
Используйте свойство DialogChoice<T>.Dock, чтобы принудительно разместить определённые кнопки первыми (задайте свойству Dock значение DockType.Left) или последними (задайте свойству Dock значение DockType.Right) среди всех кнопок. По умолчанию свойство Dock имеет значение DockType.Right.
[RelayCommand]
private void ShowDialogWithCustomButtonPlacement()
{
var result = Service<IChoiceDialogService>().Show(
DialogMessage,
DialogTitle,
new[]
{
new DialogChoice<string>("Help", "help") { Dock = DockType.Left },
new DialogChoice<string>("Retry", "retry") { IsDefault = true },
new DialogChoice<string>("Cancel", "cancel") { IsCancel = true },
});
}
Обработка закрытия диалога без выбора¶
Когда пользователь закрывает диалог кнопкой закрытия ('x'), метод Show возвращает default(T):
- Для ссылочных типов (
stringи т. д.) результат равенnull. - Для значимых типов (
bool, перечисления и т. д.) результатом является значение типа по умолчанию (falseдля логического типа,0для перечисления и т. д.)
Если в диалоге есть кнопка отмены (кнопка выбора, у которой свойство IsCancel равно true), нажатие на неё или клавиши Escape закрывает диалог с результатом этой кнопки. Кнопка закрытия ('x') по-прежнему закрывает диалог с результатом default(T).
Пример — обработка закрытия диалога¶
В этом примере создаётся диалог с кнопкой отмены, связанной с результатом диалога null. В этом случае достаточно проверить результат на null, чтобы обработать все сценарии закрытия диалога:
- Нажата кнопка отмены.
- Нажата кнопка
xв заголовке. - Нажата клавиша Escape.
var result = Service<IChoiceDialogService>().Show(
"Save the document?",
"Confirmation",
new[]
{
new DialogChoice<bool?>("Yes", true) { IsDefault = true },
new DialogChoice<bool?>("No", false),
new DialogChoice<bool?>("Cancel", null) { IsCancel = true },
});
if (result is null)
{
// Dialog was dismissed or Cancel was clicked, or Escape was pressed.
}
else if (result.Value)
{
// Yes was pressed.
}
else
{
// No was pressed.
}
* Эта страница переведена с использованием технологий машинного перевода.