This article comes from reprint
Original author: RyzenAdorer
Original title: . NET Core 3 WPF MVVM Framework Prism Series Dialog Box Services
Original link: www.cnblogs.com/ryzen/p/12771986.html
This article will introduce how to use the dialog box service of the MVVM framework Prism in a. NET Core3 environment. This is also the last concluding article in the Prism series. The following is the index to the Prism series:
.NET Core 3 WPF MVVM 框架 Prism 系列之文章索引
1. dialog box service
In Prism, dialog services are implemented through an IIalogAware interface:
public interface IDialogAware
{
bool CanCloseDialog();
void OnDialogClosed();
void OnDialogOpened(IDialogParameters parameters);
string Title { get; set; }
event Action<IDialogResult> RequestClose;
}
- The CanCloseDialog() function determines whether the form is closed
- The OnDialogClosed() function is triggered when the form is closed, and the triggering conditions depend on the CanCloseDialog() function
- The OnDialogOpened() function is triggered when the form is opened, which is triggered earlier than the Form Loaded event
- Title is the title of the form
- RequestClose is a close event that can control the closing of the form
2.1. View and ViewModel for creating a dialog box
AlertDialog.xaml:
<UserControl
x:Class="PrismMetroSample.Shell.Views.Dialogs.AlertDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PrismMetroSample.Shell.Views.Dialogs"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
Width="350"
Height="120"
prism:ViewModelLocator.AutoWireViewModel="True"
>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<image
Source="pack://application:,,,/PrismMetroSample.Infrastructure;Component/Assets/Photos/alter.png"
Height="40"
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="HighQuality"
/>
<TextBlock
Grid.Column="1"
Text="{Binding Message}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="0"
TextWrapping="Wrap"
FontSize="15"
FontFamily="Open Sans"
/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<button
Margin="5"
Foreground="White"
FontSize="12"
Background="#5cb85c"
Command="{Binding CloseDialogCommand}"
CommandParameter="true"
Content="Yes"
Width="64"
Height="28"
HorizontalAlignment="Right"
Grid.Row="1"
/>
<button
Grid.Column="1"
Margin="5"
Foreground="White"
FontSize="12"
Background="#d9534f"
Command="{Binding CloseDialogCommand}"
CommandParameter="false"
Content="No"
Width="64"
Height="28"
HorizontalAlignment="Left"
Grid.Row="1"
/>
</Grid>
</Grid>
</UserControl>
AlertDialogViewModel.cs:
public class AlertDialogViewModel : BindableBase, IDialogAware
{
private DelegateCommand<string> _closeDialogCommand;
public DelegateCommand<string> CloseDialogCommand =>
_closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand<string>(ExecuteCloseDialogCommand));
void ExecuteCloseDialogCommand(string parameter)
{
ButtonResult result = ButtonResult.None;
if (parameter?.ToLower() == "true")
result = ButtonResult.Yes;
else if (parameter?.ToLower() == "false")
result = ButtonResult.No;
RaiseRequestClose(new DialogResult(result));
}
//触发窗体关闭事件
public virtual void RaiseRequestClose(IDialogResult dialogResult)
{
RequestClose?.Invoke(dialogResult);
}
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
private string _title = "Notification";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
Message = parameters.GetValue<string>("message");
}
}
2.2. Registration dialog
App.cs:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<AlertDialog, AlertDialogViewModel>();
}
还可以注册时起名字:
Copy
containerRegistry.RegisterDialog<AlertDialog, AlertDialogViewModel>(“alertDialog”);
2.3. Using dialog services
CreateAccountViewModel.cs (modified part):
public CreateAccountViewModel(IRegionManager regionManager, IDialogService dialogService)
{
_regionManager = regionManager;
_dialogService = dialogService;
}
public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
if (!string.IsNullOrEmpty(RegisteredLoginId) && this.IsUseRequest)
{
_dialogService.ShowDialog("AlertDialog", new DialogParameters($"message={"是否需要用当前注册的用户登录?"}"), r =>
{
if (r.Result == ButtonResult.Yes)
navigationContext.Parameters.Add("loginId", RegisteredLoginId);
});
}
continuationCallback(true);
}
The effects are as follows:

We call it by calling the ShowDialog function of the IalogService interface. The following is the definition of the interface:
public interface IDialogService : Object
{
Void Show(String name, IDialogParameters parameters, Action<IDialogResult> callback);
Void ShowDialog(String name, IDialogParameters parameters, Action<IDialogResult> callback);
}
We can find that both the show and ShowDialog functions have the same formal parameters, just because the usage scenarios are different
- name: The name of the dialog box view you want to call. When registering an alias, you can only use the alias to call
- parameters: Type parameters of the IIalogParameters interface. The incoming prompt message is usually in the format of $"message=", and then obtained through the GetValue function of the IalogParameters interface through the OnDialogOpened function of the ViewModel
- callback: Used to pass in a callback function with no return value
2. Customize dialog form
As we can see above, the form of a dialog box is a form that comes with WPF. However, when we want to use our own custom form, for example, remove the Icon of the window, keep it maximize, minimize and close, or use some third-party form controls, prism supports registering a dialog box form, and then specifying the style of its dialog box form through the View of a different dialog box, which allows us to flexibly implement different dialog boxes. Let's take a look at how to do this:
2.1. Register Custom Dialog Form
Create a new form, DialogWindow.xaml:
<Window
x:Class="PrismMetroSample.Shell.Views.Dialogs.DialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
xmlns:local="clr-namespace:PrismMetroSample.Shell.Views.Dialogs"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
>
<Grid> </Grid>
</Window>
DialogWindow.xaml.cs:
public partial class DialogWindow : Window, IDialogWindow
{
public DialogWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
WindowHelp.RemoveIcon(this);//使用win32函数去除Window的Icon部分
}
public IDialogResult Result { get; set; }
}
App.cs:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow<DialogWindow>();//注册自定义对话框窗体
}
2.2. Customize dialog box form Style
AlertDialog.xaml:
<prism:Dialog.WindowStyle>
<style TargetType="Window">
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
</style>
</prism:Dialog.WindowStyle>
The effects are as follows:

How to remove all form styles and change AlertDialog.xaml:
<prism:Dialog.WindowStyle>
<style TargetType="Window">
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="WindowStyle" Value="None"/>
</style>
</prism:Dialog.WindowStyle>
Then it becomes like this:

In the end, our final effect is like this:

3. summary
Through Prism's dialog box service, we can uniformly manage the pop-up logic of dialog boxes through an IalogService interface, and we can use the dependency injection mode. If we want to define some custom dialog boxes before, we must also rely strongly on the View part. Moreover, we can customize the form styles of different dialog boxes to achieve certain flexibility (For example, the final effect demonstration uses two different dialog box styles.) At this point, the. NET Core3.x Prism series of articles have been completed
4. source code
最后,附上整个 demo 的源代码:PrismDemo 源码