Możesz to zrobić trochę bardziej "czysto"
Dodaj nową klasę
using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject>
{
/// <summary>
///
/// </summary>
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);
/// <summary>
///
/// </summary>
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command",
typeof(ICommand),
typeof(InvokeDelegateCommandAction),
null);
/// <summary>
///
/// </summary>
public static readonly DependencyProperty InvokeParameterProperty =
DependencyProperty.Register("InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);
private string commandName;
/// <summary>
///
/// </summary>
public object InvokeParameter
{
get
{
return this.GetValue(InvokeParameterProperty);
}
set
{
this.SetValue(InvokeParameterProperty, value);
}
}
/// <summary>
///
/// </summary>
public ICommand Command
{
get
{
return (ICommand)this.GetValue(CommandProperty);
}
set
{
this.SetValue(CommandProperty, value);
}
}
/// <summary>
///
/// </summary>
public string CommandName
{
get
{
return this.commandName;
}
set
{
if (this.CommandName != value)
{
this.commandName = value;
}
}
}
/// <summary>
///
/// </summary>
public object CommandParameter
{
get
{
return this.GetValue(CommandParameterProperty);
}
set
{
this.SetValue(CommandParameterProperty, value);
}
}
/// <summary>
///
/// </summary>
/// <param name="parameter"></param>
protected override void Invoke(object parameter)
{
this.InvokeParameter = parameter;
if (this.AssociatedObject != null)
{
ICommand command = this.ResolveCommand();
if ((command != null) && command.CanExecute(this.CommandParameter))
{
command.Execute(this.CommandParameter);
}
}
}
private ICommand ResolveCommand()
{
ICommand command = null;
if (this.Command != null)
{
return this.Command;
}
var frameworkElement = this.AssociatedObject as FrameworkElement;
if (frameworkElement != null)
{
object dataContext = frameworkElement.DataContext;
if (dataContext != null)
{
PropertyInfo commandPropertyInfo =
dataContext.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(
p =>
typeof(ICommand).IsAssignableFrom(p.PropertyType)
&& string.Equals(p.Name, this.CommandName, StringComparison.Ordinal));
if (commandPropertyInfo != null)
{
command = (ICommand)commandPropertyInfo.GetValue(dataContext, null);
}
}
}
return command;
}
}
teraz w xmla dopisujesz obsługę eventów
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<local:InvokeDelegateCommandAction Command="{Binding WindowClosingCommand, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}" />
</i:EventTrigger>
<i:EventTrigger EventName="Closed">
<i:InvokeCommandAction Command="{Binding WindowClosedCommand, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</i:EventTrigger>
</i:Interaction.Triggers>
i teraz z ViewModel masz 2 funkcje
public ICommand WindowClosedCommand
{
get
{
return new DelegateCommand(this.Dispose, () => true);
}
}
public ICommand WindowClosingCommand
{
get
{
return new DelegateCommand<CancelEventArgs>(
e =>
{
var result = this.dialogService.ShowMessageBox(
this,
"Do you want to close this window",
"Question...",
MessageBoxButton.YesNo);
e.Cancel = result != MessageBoxResult.Yes;
});
}
}
DelegateCommand pochodzi z Prism a dialogService z
Pozdrawiam,
mr-owl