非常好的使用视图模型方式做到这一点的例子可以在Nish Nishant的文章中找到
(链接),他使用附加属性将窗口事件与命令连接起来。
附加行为的示例代码(代码作者:
Nish Nishant)。
public class WindowClosingBehavior {
public static ICommand GetClosed(DependencyObject obj) {
return (ICommand)obj.GetValue(ClosedProperty);
}
public static void SetClosed(DependencyObject obj, ICommand value) {
obj.SetValue(ClosedProperty, value);
}
public static readonly DependencyProperty ClosedProperty
= DependencyProperty.RegisterAttached(
"Closed", typeof(ICommand), typeof(WindowClosingBehavior),
new UIPropertyMetadata(new PropertyChangedCallback(ClosedChanged)));
private static void ClosedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) {
Window window = target as Window;
if (window != null) {
if (e.NewValue != null) {
window.Closed += Window_Closed;
}
else {
window.Closed -= Window_Closed;
}
}
}
public static ICommand GetClosing(DependencyObject obj) {
return (ICommand)obj.GetValue(ClosingProperty);
}
public static void SetClosing(DependencyObject obj, ICommand value) {
obj.SetValue(ClosingProperty, value);
}
public static readonly DependencyProperty ClosingProperty
= DependencyProperty.RegisterAttached(
"Closing", typeof(ICommand), typeof(WindowClosingBehavior),
new UIPropertyMetadata(new PropertyChangedCallback(ClosingChanged)));
private static void ClosingChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) {
Window window = target as Window;
if (window != null) {
if (e.NewValue != null) {
window.Closing += Window_Closing;
}
else {
window.Closing -= Window_Closing;
}
}
}
public static ICommand GetCancelClosing(DependencyObject obj) {
return (ICommand)obj.GetValue(CancelClosingProperty);
}
public static void SetCancelClosing(DependencyObject obj, ICommand value) {
obj.SetValue(CancelClosingProperty, value);
}
public static readonly DependencyProperty CancelClosingProperty
= DependencyProperty.RegisterAttached(
"CancelClosing", typeof(ICommand), typeof(WindowClosingBehavior));
static void Window_Closed(object sender, EventArgs e) {
ICommand closed = GetClosed(sender as Window);
if (closed != null) {
closed.Execute(null);
}
}
static void Window_Closing(object sender, CancelEventArgs e) {
ICommand closing = GetClosing(sender as Window);
if (closing != null) {
if (closing.CanExecute(null)) {
closing.Execute(null);
}
else {
ICommand cancelClosing = GetCancelClosing(sender as Window);
if (cancelClosing != null) {
cancelClosing.Execute(null);
}
e.Cancel = true;
}
}
}
}
绑定命令的示例:
<Window
x:Class="WindowClosingDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nsmvvm="clr-namespace:NS.MVVM"
nsmvvm:WindowClosingBehavior.Closed="{Binding ClosedCommand}"
nsmvvm:WindowClosingBehavior.Closing="{Binding ClosingCommand}"
nsmvvm:WindowClosingBehavior.CancelClosing="{Binding CancelClosingCommand}">
“ClosedCommand”、“ClosingCommand”和“CancelClosingCommand”命令应在单独的视图模型中定义。
internal class MainViewModel : ViewModelBase {
private ObservableCollection<string> log = new ObservableCollection<string>();
public ObservableCollection<string> Log {
get { return log; }
}
private DelegateCommand exitCommand;
public ICommand ExitCommand {
get {
if (exitCommand == null) {
exitCommand = new DelegateCommand(Exit);
}
return exitCommand;
}
}
private void Exit() {
Application.Current.Shutdown();
}
private DelegateCommand closedCommand;
public ICommand ClosedCommand {
get {
if (closedCommand == null) {
closedCommand = new DelegateCommand(Closed);
}
return closedCommand;
}
}
private void Closed() {
log.Add("You won't see this of course! Closed command executed");
MessageBox.Show("Closed");
}
private DelegateCommand closingCommand;
public ICommand ClosingCommand {
get {
if (closingCommand == null) {
closingCommand = new DelegateCommand(ExecuteClosing, CanExecuteClosing);
}
return closingCommand;
}
}
private void ExecuteClosing() {
log.Add("Closing command executed");
MessageBox.Show("Closing");
}
private bool CanExecuteClosing() {
log.Add("Closing command execution check");
return MessageBox.Show("OK to close?", "Confirm", MessageBoxButton.YesNo) == MessageBoxResult.Yes;
}
private DelegateCommand cancelClosingCommand;
public ICommand CancelClosingCommand {
get {
if (cancelClosingCommand == null) {
cancelClosingCommand = new DelegateCommand(CancelClosing);
}
return cancelClosingCommand;
}
}
private void CancelClosing() {
log.Add("CancelClosing command executed");
MessageBox.Show("CancelClosing");
}
}
viewModel.TryClose(false)
函数是否会向视图发送事件以关闭对话框?如果是,则可以从xaml代码中删除IsCancel="true"
。这部分会导致表单关闭。 - Yusuf Tarık GünaydınKeyBinding
。这里有一个例子。 - Yusuf Tarık Günaydın