MVVM Light の DialogMessage 用の ビヘイビア (Behavior) を作ってみた。
これで UnitTest も問題ない。
DialogMessageAction.cs
using System.Windows;
using System.Windows.Interactivity;
using GalaSoft.MvvmLight.Messaging;
namespace BehaviorsSample
{
public class DialogMessageAction : TriggerAction<DependencyObject>
{
public DialogMessageAction()
{
}
protected override void Invoke(object parameter)
{
DialogMessage message = parameter as DialogMessage;
if (message != null)
{
MessageBoxResult result = MessageBox.Show(message.Content, message.Caption, message.Button);
message.Callback(result);
}
}
}
}
DialogMessageTrigger.cs
using System.Windows;
using System.Windows.Interactivity;
using GalaSoft.MvvmLight.Messaging;
namespace BehaviorsSample
{
public class DialogMessageTrigger : TriggerBase<DependencyObject>
{
protected override void OnAttached()
{
base.OnAttached();
Messenger.Default.Register<DialogMessage>(base.AssociatedObject,
p => this.InvokeActions(p));
}
protected override void OnDetaching()
{
base.OnDetaching();
Messenger.Default.Unregister<DialogMessage>(base.AssociatedObject);
}
}
}
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
xmlns:local="clr-namespace:BehaviorsSample"
x:Name="window" x:Class="Window"
Title="MainWindow" Height="300" Width="300"
>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<i:Interaction.Triggers>
<local:DialogMessageTrigger>
<local:DialogMessageAction/>
</local:DialogMessageTrigger>
</i:Interaction.Triggers>
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Window.DataContext>
<Grid x:Name="LayoutRoot">
<Button x:Name="ExecuteButton" Width="100" Height="100" Content="実行">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ShutdownCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</Window>
MainWindow.cs は消してます。
http://blogs.wankuma.com/mnow/archive/2010/11/10/194751.aspx
MainViewModel.cs
using System.ComponentModel;
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
namespace BehaviorsSample.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
if (IsInDesignMode)
{
}
else
{
}
ShutdownCommand = new RelayCommand(() => Shutdown());
}
private RelayCommand _shutdownCommand;
public RelayCommand ShutdownCommand
{
get
{
return _shutdownCommand;
}
private set
{
_shutdownCommand = value;
RaisePropertyChanged("ShutdownCommand");
}
}
private void Shutdown()
{
if (ConfirmShutdown())
{
App.Current.Shutdown();
}
}
private MessageBoxResult _messageBoxResult;
private bool ConfirmShutdown()
{
DialogMessage message = new DialogMessage("終了してよろしいですか", p => ShutdownCallback(p));
message.Caption = "終了確認";
message.Button = MessageBoxButton.OKCancel;
message.Icon = MessageBoxImage.Question;
_messageBoxResult = MessageBoxResult.Cancel;
Messenger.Default.Send<DialogMessage>(message);
if (_messageBoxResult == MessageBoxResult.OK)
{
return true;
}
return false;
}
private void ShutdownCallback(MessageBoxResult result)
{
_messageBoxResult = result;
if (result == MessageBoxResult.OK)
{
ViewModelLocator.Cleanup();
}
}
public override void Cleanup()
{
_shutdownCommand = null;
base.Cleanup();
}
}
}