Открытие диалогового окна
На этой страницу вы узнаете, как используя ReactiveUI можно управлять другим окном в приложении. Новое окно будет иметь возможность поиска, а также кнопку для добавления одного из найденных альбомов в список основного окна. Новое окно будет открывать как диалоговое, из-за чего, во время его отображения, основное окно будет блокироваться.
Добавление нового диалогового окна
В самом файле window view
нет ничего, что может сделать его диалоговым.
Это зависит от способа управления окном в приложении, и для этих целей вы будете использовать ReactiveUI.
Для создания нового окна, выполните следующие действия:
- Остановите приложение, если оно запущено.
- В обозревателе решений, нажмите ПКМ по папке /Views и выберите Add.
- Нажмите Avalonia Window.
- Когда будет предложено ввести название, укажите 'MusicStoreWindow'
- Нажмите
Enter
.
Стилизация диалогового окна
Для стилизации нового диалогового окна, также как и в основном окне, выполните следующие действия:
- Найдите и откройте файл MusicStoreWindow.axaml.
- Для добавления акрилового размытия фона и строки заголовка, измените код, как показано ниже:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Avalonia.MusicStore.Views.MusicStoreWindow"
Title="MusicStoreWindow"
TransparencyLevelHint="AcrylicBlur"
ExtendClientAreaToDecorationsHint="True">
<Panel>
<ExperimentalAcrylicBorder IsHitTestVisible="False">
<ExperimentalAcrylicBorder.Material>
<ExperimentalAcrylicMaterial
BackgroundSource="Digger"
TintColor="Black"
TintOpacity="1"
MaterialOpacity="0.65" />
</ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder>
<Panel Margin="40">
</Panel>
</Panel>
</Window>
Ввод и вывод диалогового окна
Работа диалогового окна будет обрабатываться его собственной view model
.
Она будет создана и связана с ним в момент, к огда диалоговое окно должно будет отобразиться.
Аналогичным образом, результат взаимодействия пользователя с диалоговым окном, должен быть передан обратно для обработки в основном окне.
На этом этапе вы создадите два пустых класса view model
, которые будут выступать в качестве заполнителей для dialog view model
и объекта dialog return
(выбранный альбом).
Выполните следующие действия:
- В обозревателе решений нажмите ПКМ по папке /ViewModels и выберите Add.
- Нажмите Class.
- Укажите имя класса 'MusicStoreViewModel' и выберите Add.
- Повторно нажмите ПКМ по папке /ViewModels и выберите Add.
- Нажмите Class.
- Укажите имя класса 'AlbumViewModel' и выберите Add.
Отображение диалогового окна
Теперь у нас есть новое окно, которое можно будет использовать как диалоговое.
А также классы view model
для взаимодействия с ним. Для создания самого взаимодействия, нужно выполнить 2 условия:
View model
основного окна запускает взаимодействие.View
основного окна знает "как" начать взаимодействие.
Первым делом изменим код view model
основного окна так,
чтобы он запускал взаимодействие для отображения диалогового окна.
Выполните следующие действия:
- Найдите и откройте файл MainWindowViewModel.cs.
- Добавьте объявление взаимодействия с новым диалоговым окном, как показано ниже:
public Interaction<MusicStoreViewModel, AlbumViewModel?> ShowDialog { get; }
- Для создания реактивной команды из асинхронный задачи, измените код конструктора, как показано ниже:
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Text;
using System.Windows.Input;
using ReactiveUI;
namespace Avalonia.MusicStore.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
ShowDialog = new Interaction<MusicStoreViewModel, AlbumViewModel?>();
BuyMusicCommand = ReactiveCommand.CreateFromTask(async () =>
{
var store = new MusicStoreViewModel();
var result = await ShowDialog.Handle(store);
});
}
public ICommand BuyMusicCommand { get; }
public Interaction<MusicStoreViewModel, AlbumViewModel?> ShowDialog { get; }
}
}
На данный момент, код для взаимодействия все еще не закончен.
При запуске приложения и попытке нажать кнопку с иконой, вы получите исключение ReactiveUI.UnhandledInteractionException
.
Нашим следующим шагом станет внесение изменений во view
основного окна, чтобы она знала "как" запустить взаимодействие.
Они добавляются в код нашей view
, и используют функционал из фреймворка ReactiveUI.
Выполните указанные ниже действия:
- Найдите и откройте файл MainWindow.axaml.cs. (Чтобы найти его, вы можете раскрыть файл MainWindow.axaml)
- Измените класс, чтобы он наследовался от
ReactiveWindow<MainWindowViewModel>
. - Добавьте метод
DoShowDialogAsync
, как показано ниже:
// This code is only valid in newer ReactiveUI which is shipped since avalonia 11.2.0
private async Task DoShowDialogAsync(IInteractionContext<MusicStoreViewModel,
AlbumViewModel?> interaction)
{
var dialog = new MusicStoreWindow();
dialog.DataContext = interaction.Input;
var result = await dialog.ShowDialog<AlbumViewModel?>(this);
interaction.SetOutput(result);
}
- В конец конструктора добавьте следующий код:
this.WhenActivated(action =>
action(ViewModel!.ShowDialog.RegisterHandler(DoShowDialogAsync)));
Данный код означает, что когда активируется view
основного окна, то регистрируется событие DoShowDialogAsync
,
Данное действие является disposable
, поэтому ReactiveUI может очистить регистрацию,
когда view
основного экрана уйдет с экрана.
Теперь ваш файл должен выглядеть следующим образом:
using Avalonia.ReactiveUI;
using Avalonia.MusicStore.ViewModels;
using ReactiveUI;
using System.Threading.Tasks;
namespace Avalonia.MusicStore.Views
{
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
{
public MainWindow()
{
InitializeComponent();
this.WhenActivated(action =>
action(ViewModel!.ShowDialog.RegisterHandler(DoShowDialogAsync)));
}
private async Task DoShowDialogAsync(IInteractionContext<MusicStoreViewModel,
AlbumViewModel?> interaction)
{
var dialog = new MusicStoreWindow();
dialog.DataContext = interaction.Input;
var result = await dialog.ShowDialog<AlbumViewModel?>(this);
interaction.SetOutput(result);
}
}
}
- Нажмите Debug для сборки и запуска проекта.
- Нажмите кнопку с иконкой.
Все работает, но диалоговое окно имеет такой же размер что и основное, а также сдвинуто от него.
Позиция и размер диалогового окна
На заключительном этапе, вы уменьшите размер диалогового окна относительно основного, но и разместите прямо по его центру. Вы также настроите, чтобы основное окно открывалось по центру экрана пользователя.
Выполните следующие действия:
- Остановите приложение, если оно запущено.
- Найдите и откройте файл MainWindow.axaml.
- К элементу
<Window>
, добавьте атрибут, как показано ниже:
<Window ...
WindowStartupLocation="CenterScreen">
- Найдите и откройте файл MusicStoreWindow.axaml.
- В диалоговое окно добавьте атрибуты ширины и высоты, а их значения установите
1000
и500
, соответственно. - Добавьте атрибут начальной позиции измените его значение на
CenterOwner
, как показано ниже:
<Window ...
Width="1000" Height="550"
WindowStartupLocation="CenterOwner">
- Нажмите Debug для сборки и запуска проекта.
- Нажмите кнопку с иконкой.
Теперь диалоговое окно открывается прямо по центру, внутри основного окна.
На следующей странице вы узнаете, как изменить содержимое диалогового окна для поиска альбомов и их отображения.