IWindowService¶
IWindowService предоставляет платформенно-независимый способ показывать немодальные окна из ViewModel. ViewModel при этом остаются полностью отделёнными от типов окон Avalonia.
Основные возможности:
- Отображение немодальных окон.
- Окна, управляемые ViewModel — Отображаемое окно определяется собственной ViewModel. Содержимое окна можно задать с помощью свойства
ContentViewModel или с помощью атрибутаViewLocatorAttribute, применённого к ViewModel окна. - Автоматический владелец — Владельцем окна становится активное окно приложения. Активное окно автоматически определяется через сервис
IWindowsManager.
Определение интерфейса¶
public interface IWindowService
{
// Show a non-modal window driven by a ViewModel.
void Show<T>(T viewModel, string? caption = null)
where T : IWindowAwareViewModel;
}
| Параметр | Тип | Описание |
|---|---|---|
viewModel |
T |
ViewModel отображаемого окна. Объект viewModel должен реализовывать интерфейс IWindowAwareViewModel. ViewModel окна можно унаследовать от класса WindowAwareViewModel, который уже реализует этот интерфейс и добавляет инфраструктуру поиска View. |
caption |
string? |
Заголовок окна. Если задано значение null, заголовок берётся из свойства Title ViewModel (IWindowAwareViewModel.Title). |
Метод Show возвращает управление сразу после отображения окна и не ожидает его закрытия.
Исключения:
ArgumentNullException— Если параметрviewModelравенnull.
Как использовать IWindowService¶
- Создайте ViewModel для отображаемого немодального окна. Например, её можно унаследовать от класса
WindowAwareViewModel. -
Задайте содержимое окна одним из следующих способов:
- Определите View (
UserControl), представляющее содержимое окна. Примените к ViewModel атрибутViewLocatorAttribute, чтобы связать эту ViewModel с созданным View. - Явно задайте свойство
ContentViewModel окна (WindowAwareViewModel.Content).
- Определите View (
-
В ViewModel, из которой нужно показать окно, вызовите метод
IWindowService.Show. Передайте методуShowViewModel отображаемого окна. МетодShowсразу возвращает управление, а показанное окно остаётся открытым, пока пользователь его не закроет.
Доступ к сервису¶
Получить объект IWindowService в ViewModel можно двумя способами:
- С помощью вспомогательного метода
Service<T>(). Это удобный способ получить зарегистрированные сервисы приложения, входящие в библиотеку Eremex Controls. - Через внедрение в конструктор.
Вспомогательный метод Service()¶
Реализуйте в ViewModel вспомогательный метод Service<T>(), который получает запрошенный сервис с помощью статического метода ApplicationServicesContext.GetRequiredService<T>().
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 ShowWindow()
{
// Resolve the service and show the window
Service<IWindowService>().Show(
new MyWindowViewModel("Non-modal window"));
}
}
Убедитесь, что в файле 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 конструктор с параметром типа IWindowService. При создании ViewModel передайте объект сервиса в этот конструктор.
public partial class MyViewModel
{
private readonly IWindowService _windowService;
public MyViewModel(IWindowService windowService)
{
_windowService = windowService;
}
[RelayCommand]
private void ShowWindow()
{
_windowService.Show(new MyWindowViewModel("Non-modal window"));
}
}
Создание ViewModel окна¶
Для отображаемого немодального окна нужно создать ViewModel. ViewModel должна реализовывать интерфейс IWindowAwareViewModel. Проще всего унаследовать ViewModel от класса WindowAwareViewModel, который уже реализует интерфейс IWindowAwareViewModel и выполняет поиск View.
Определение содержимого окна с помощью ViewLocatorAttribute¶
- Создайте View (
UserControl) с контролами, которые нужно отобразить в окне. - Пометьте ViewModel окна атрибутом
ViewLocatorAttribute, передав ему тип View.
При вызове метода IWindowService.Show ViewModel создаёт окно Avalonia, создаёт экземпляр указанного View (UserControl) и помещает его в окно в качестве содержимого. ViewModel никогда не нужно ссылаться на тип View напрямую.
Пример¶
В этом примере сервис IWindowService используется для отображения немодального окна, содержимое которого задано собственным View.
Полный код приведён в демонстрационном приложении Controls Demo.
ViewModel немодального окна
using Eremex.AvaloniaUI.Controls.ApplicationServices;
[ViewLocator(typeof(WindowServiceWindowView))]
public class WindowServiceWindowViewModel : WindowAwareViewModel
{
private string statusText;
public string StatusText
{
get => statusText;
private set
{
if (statusText == value)
return;
statusText = value;
OnPropertyChanged(nameof(StatusText));
}
}
}
Содержимое немодального окна (View)
<UserControl x:Class="DemoCenter.Views.ApplicationServices.WindowServiceWindowView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:DemoCenter.ViewModels.ApplicationServices"
x:CompileBindings="True"
x:DataType="vm:WindowServiceWindowViewModel"
MinWidth="420">
<StackPanel Margin="20" Spacing="12">
<TextBlock Text="Window content"
TextWrapping="Wrap" />
</StackPanel>
</UserControl>
Отображение окна
[RelayCommand]
private void ShowWindow()
{
string windowTitle = "Non-modal window";
Service<IWindowService>().Show(new WindowServiceWindowViewModel(windowTitle));
}
Непосредственное определение содержимого окна¶
Чтобы явно задать содержимое окна, используйте свойство Content ViewModel (WindowAwareViewModel.Content).
using Eremex.AvaloniaUI.Controls.ApplicationServices;
public class MyWindowViewModel : WindowAwareViewModel
{
public MyWindowViewModel(string title) : base(title)
{
Content = "Window content";
}
}
Чтобы показать это окно, используйте следующий код:
Заголовок окна¶
Заголовок окна можно задать одним из следующих способов:
- Задайте параметр
captionметодаIWindowService.Show. - Задайте свойство
TitleViewModel окна. Это свойство действует, если параметрcaptionметодаIWindowService.Showравенnull.
Окно-владелец¶
Владелец определяется автоматически через сервис IWindowsManager. Владельцем окна становится активное окно приложения, возвращаемое этим сервисом.
* Эта страница переведена с использованием технологий машинного перевода.
