Prism对话框之自定义DialogWindow
1. 自定义DialogWindow窗体样式
(1)定义DialogWindow窗体类,注意要实现IDialogWindow
/// <summary>
/// CustomDialogWindow.xaml 的交互逻辑
/// </summary>
public partial class CustomDialogWindow : Window, IDialogWindow
{
public IDialogResult Result { get; set; }
public CustomDialogWindow()
{
InitializeComponent();
DefaultStyleKey = typeof(CustomDialogWindow);
CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, (_, __) => { SystemCommands.CloseWindow(this); }));
CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, (_, __) => { SystemCommands.MinimizeWindow(this); }));
CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, (_, __) => { SystemCommands.MaximizeWindow(this); }));
CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, (_, __) => { SystemCommands.RestoreWindow(this); }));
SizeToContent = SizeToContent.WidthAndHeight;
ResizeMode = ResizeMode.NoResize;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
if (SizeToContent == SizeToContent.WidthAndHeight && WindowChrome.GetWindowChrome(this) != null)
{
InvalidateMeasure();
}
}
}
(2)样式文件CustomDialogWindow.xaml
<Style TargetType="{x:Type ctrls:CustomDialogWindow}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="#FF0874AA" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="WindowStyle" Value="SingleBorderWindow"/>
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CornerRadius="0"
GlassFrameThickness="1"
UseAeroCaptionButtons="False"
NonClientFrameEdges="None" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrls:CustomDialogWindow}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
x:Name="WindowBorder">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="PART_WindowTitleGrid"
Grid.Row="0"
Height="26.4"
Background="{TemplateBinding BorderBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Button VerticalAlignment="Center"
Margin="7,0,5,0"
Content="{TemplateBinding Icon}"
Height="{x:Static SystemParameters.SmallIconHeight}"
Width="{x:Static SystemParameters.SmallIconWidth}"
WindowChrome.IsHitTestVisibleInChrome="True"
IsTabStop="False">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Image Source="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{x:Static SystemCommands.ShowSystemMenuCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{x:Static SystemCommands.CloseWindowCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<ContentControl IsTabStop="False"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="{DynamicResource {x:Static SystemFonts.CaptionFontSize}}"
Content="{TemplateBinding Title}" />
</StackPanel>
<StackPanel x:Name="WindowCommandButtonsStackPanel"
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Transparent"
Orientation="Horizontal"
WindowChrome.IsHitTestVisibleInChrome="True"
Margin="0,-1,-1,0">
<Button x:Name="Minimize"
ToolTip="Minimize"
WindowChrome.IsHitTestVisibleInChrome="True"
Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}"
ContentTemplate="{StaticResource MinimizeWhite}"
Style="{StaticResource CaptionButtonStyle}"
IsTabStop="False" />
<Grid Margin="1,0,1,0">
<Button x:Name="Restore"
ToolTip="Restore"
WindowChrome.IsHitTestVisibleInChrome="True"
Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}"
ContentTemplate="{StaticResource RestoreWhite}"
Style="{StaticResource CaptionButtonStyle}"
Visibility="Collapsed"
IsTabStop="False" />
<Button x:Name="Maximize"
ToolTip="Maximize"
WindowChrome.IsHitTestVisibleInChrome="True"
Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}"
ContentTemplate="{StaticResource MaximizeWhite}"
Style="{StaticResource CaptionButtonStyle}"
IsTabStop="False" />
</Grid>
<Button x:Name="Close"
ToolTip="Close"
Background="Red"
WindowChrome.IsHitTestVisibleInChrome="True"
Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}"
ContentTemplate="{StaticResource CloseWhite}"
Style="{StaticResource CaptionButtonStyle}"
IsTabStop="False" />
</StackPanel>
</Grid>
<AdornerDecorator Grid.Row="1"
KeyboardNavigation.IsTabStop="False">
<ContentPresenter Content="{TemplateBinding Content}"
x:Name="MainContentPresenter"
KeyboardNavigation.TabNavigation="Cycle" />
</AdornerDecorator>
<ResizeGrip x:Name="ResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Grid.Row="1"
IsTabStop="False"
Visibility="Hidden"
WindowChrome.ResizeGripDirection="BottomRight" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsActive" Value="False">
<Setter Property="BorderBrush" Value="#FF6F7785" />
</Trigger>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
<Setter TargetName="Restore" Property="Visibility" Value="Visible" />
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="WindowState" Value="Normal">
<Setter TargetName="Maximize" Property="Visibility" Value="Visible" />
<Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="ResizeMode" Value="NoResize">
<Setter TargetName="Minimize" Property="Visibility" Value="Collapsed" />
<Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
<Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip" />
<Condition Property="WindowState" Value="Normal" />
</MultiTrigger.Conditions>
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2. 定义对话窗View和ViewModel
(1)DialogView
<UserControl x:Class="CustomDialogWindow.Views.DialogView"
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:CustomDialogWindow.Views"
mc:Ignorable="d" Width="450" Height="300" Background="White">
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30" Text="这是一个Prism对话框"></TextBlock>
</Grid>
</UserControl>
(2)DialogViewModel
public class DialogViewModel : BindableBase, IDialogAware
{
public event Action<IDialogResult> RequestClose;
#region Commands
public DelegateCommand<string> ExcuteCommand { get; set; }
#endregion
private string title = "Title";
public string Title
{
get { return title; }
set { title = value; RaisePropertyChanged(); }
}
public DialogViewModel()
{
ExcuteCommand = new DelegateCommand<string>(Excute);
}
private void Excute(string name)
{
if ("YES".Equals(name))
{
RequestClose.Invoke(new DialogResult(ButtonResult.Yes));
}
else if ("Cancel".Equals(name))
{
RequestClose.Invoke(new DialogResult(ButtonResult.Cancel));
}
}
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
if (parameters.ContainsKey("Title"))
{
this.Title = parameters.GetValue<string>("Title");
}
}
}
3.定义MainWindow对应的ViewModel
public class MainWindowViewModel : BindableBase
{
#region commands
public DelegateCommand OpenCustomDialogCommand { get; set; }
public DelegateCommand OpenDefalutDialogCommand { get; set; }
#endregion
#region Fields
private IContainerProvider container;
#endregion
#region Constructor
public MainWindowViewModel(IContainerProvider containerProvider)
{
container = containerProvider;
OpenCustomDialogCommand = new DelegateCommand(OpenCustomDialog);
OpenDefalutDialogCommand = new DelegateCommand(OpenDefalutDialog);
}
private void OpenDefalutDialog()
{
IDialogService dialogService = container.Resolve<IDialogService>();
IDialogParameters parameters = new DialogParameters();
parameters.Add("Title", "DefaultDialogWindow");
dialogService.ShowDialog("DialogView", parameters, null);
}
private void OpenCustomDialog()
{
IDialogService dialogService = container.Resolve<IDialogService>();
IDialogParameters parameters = new DialogParameters();
parameters.Add("Title", "CustomDialogWindow");
dialogService.ShowDialog("DialogView", parameters, null, "CustomDialogWindow");
}
#endregion
}
4. 注册DialogWindow、View、ViewModel
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow<Controls.Windows.CustomDialogWindow>("CustomDialogWindow");
containerRegistry.RegisterForNavigation<MainWindow, MainWindowViewModel>();
containerRegistry.RegisterDialog<DialogView, DialogViewModel>("DialogView");
}
}
5.运行效果
(1)自定义对话框窗体效果:
(2)默认对话框窗体效果