ダイアログに関しては以前の記事でも取り上げましたが、以下のサイトが参考になるでしょう。
Interactivity Code Sample using the Prism Library 5.0 for WPF in C# for Visual Studio 2013
これを踏まえてちょこっとだけカスタマイズしてみます。
標準のダイアログの外観
カスタマイズしたダイアログの外観
Windows7風。
標準の使い方(View、ConfirmationRequest)
<UserControl x:Class="SampleView" 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:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:prism="http://www.codeplex.com/prism" mc:Ignorable="d" DataContext="{Binding LoginViewModel, Source={StaticResource Locator}}"> <i:Interaction.Triggers> <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}"> <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/> </prism:InteractionRequestTrigger> </i:Interaction.Triggers> <Grid> <!--略--> </Grid> </UserControl>
prism:PopupWindowAction
のプロパティの意味は以下の通り。
IsModel="True"
≒Window.ShowDialog
IsModel="False"
≒Window.Show
CenterOverAssociatedObject=True
≒WindowStartupLocation="CenterScreen"
CenterOverAssociatedObject=False
≒WindowStartupLocation="Manual"
標準の使い方(ViewModel)
Imports Microsoft.Practices.Prism.Mvvm Imports Microsoft.Practices.Prism.Commands Imports Microsoft.Practices.Prism.Interactivity.InteractionRequest Imports System.Runtime.InteropServices Public Class SampleViewModel Inherits BindableBase 'Commandのコードは省略 Private Sub OnExecute() If Me.RaiseConfirm = False Then Return 'TODO:実処理 End Sub Public Function RaiseConfirm() As Boolean 'コールバック格納変数 Dim isConfirm As Boolean = True 'View側で受けるコードがない場合はコールバックされません。 Me.ConfirmationRequest.Raise( New Confirmation With {.Content = "実行しますよろしいですか?", .Title = "確認"}, Sub(c) isConfirm = c.Confirmed) Return isConfirm End Function Private _confirmationRequest As New InteractionRequest(Of IConfirmation) ''' <summary> ''' 確認リクエスト ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property ConfirmationRequest As InteractionRequest(Of IConfirmation) Get Return _confirmationRequest End Get Private Set(value As InteractionRequest(Of IConfirmation)) _confirmationRequest = value End Set End Property End Class
これはサンプルのコードほぼそのまま、かつそのまま特記事項もないので省略。これで確認ダイアログが表示できます。
カスタマイズしたダイアログの使い方(View、ConfirmationRequest)
View部分を自分で作成したUserControlに差し替えます。
まずは見た目となるViewのコードから。
<UserControl x:Class="ConfirmView" 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" mc:Ignorable="d"> <DockPanel MinWidth="400"> <DockPanel DockPanel.Dock="Bottom" Background="#F0F0F0" > <Grid Margin="8" > <Grid.Resources> <Style TargetType="Button" x:Key="ReturnButton" > <Setter Property="Padding" Value="3" /> <Setter Property="Margin" Value="6,0,0,0" /> </Style> </Grid.Resources> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="104" /> <ColumnDefinition Width="104" /> </Grid.ColumnDefinitions> <Button Grid.Column="1" Content="OK" Command="{Binding OkCommand}" Style="{StaticResource ReturnButton}" IsDefault="True"/> <Button Grid.Column="3" Content="キャンセル" Command="{Binding CancelCommand}" Style="{StaticResource ReturnButton}" IsCancel="True" /> </Grid> </DockPanel> <TextBlock Margin="8,8,8,16" MinHeight="48" Text="{Binding Notification.Content}" /> </DockPanel> </UserControl>
そしてViewModel。OKボタン押下時、戻り値をセットして、Me.FinishInteraction.Invoke()
を発生させる。Cancelボタン押下時も同様。
Imports Microsoft.Practices.Prism.Mvvm Imports Microsoft.Practices.Prism.Interactivity.InteractionRequest Imports Microsoft.Practices.Prism.Commands Public Class ConfirmViewModel Inherits BindableBase Implements IInteractionRequestAware Public Sub New() Me.OkCommand = New DelegateCommand(AddressOf Me.OnOk) Me.CancelCommand = New DelegateCommand(AddressOf Me.OnCancel) End Sub Public Property OkCommand As DelegateCommand Public Sub OnOk() Me.Confirmation.Confirmed = True Me.FinishInteraction.Invoke() End Sub Public Property CancelCommand As DelegateCommand Public Sub OnCancel() Me.Confirmation.Confirmed = False Me.FinishInteraction.Invoke() End Sub #Region "IInteractionRequestAware" Public Property FinishInteraction As Action Implements IInteractionRequestAware.FinishInteraction Private _notification As INotification Public Property Notification As INotification Implements IInteractionRequestAware.Notification Get Return _notification End Get Set(value As INotification) Me.SetProperty(_notification, value) End Set End Property Private ReadOnly Property Confirmation As Confirmation Get Return DirectCast(Me.Notification, Confirmation) End Get End Property #End Region End Class
ViewとViewModelの紐づけはコードビハインドで。
Public Class ConfirmView Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 Me.DataContext = New ConfirmViewModel End Sub End Class
最後に呼び出し元のコードを以下のように変更して完成。
変更前
<i:Interaction.Triggers> <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}"> <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/> </prism:InteractionRequestTrigger> </i:Interaction.Triggers>
変更後
<i:Interaction.Triggers> <prism:InteractionRequestTrigger SourceObject="{Binding LeaveConfirmationRequest, Mode=OneWay}"> <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"> <prism:PopupWindowAction.WindowContent> <local:LeaveConfirmView /> </prism:PopupWindowAction.WindowContent> </prism:PopupWindowAction> </prism:InteractionRequestTrigger> </i:Interaction.Triggers>
カスタムな戻り値
2択の場合はConfirmationで良かったですが、先に挙げた3択のようにしたい場合は、独自のNotification
クラスを作って…
Imports Microsoft.Practices.Prism.Interactivity.InteractionRequest Public Class LeaveNotification Inherits Notification Public Property Answer As LeaveConfirmAnswer End Class Public Enum LeaveConfirmAnswer ''' <summary> ''' 保存して移動 ''' </summary> ''' <remarks></remarks> SaveAndLeave ''' <summary> ''' 保存せずに移動 ''' </summary> ''' <remarks></remarks> NotSaveAndLeave ''' <summary> ''' 移動自体を取りやめる ''' </summary> ''' <remarks></remarks> Cancel End Enum
専用のViewを作って(ここはまるっと省略)…
専用のViewModelを作って…
Public Class LeaveConfirmViewModel '略 Public Property SaveAndLeaveCommand As DelegateCommand Public Sub OnSaveAndLeave() Me.LeaveNotification.Answer = LeaveConfirmAnswer.SaveAndLeave Me.FinishInteraction.Invoke() End Sub '略 End Class
コードビハインドでViewとViewModelを紐づけたら完成。