<Window x:Class="AVA.Meeting.Client.Text"        
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:z="clr-namespace:Z.Core.WPF;assembly=Z.Core.WPF"
        z:Closed.Command="{Binding OnClosed}">
    <StackPanel>
        <Button Content="关闭窗体" Command="{Binding OnClosed}" />
    </StackPanel>
</Window>
using Microsoft.Practices.Prism.Commands;
using System.Windows;
using System.Windows.Input;namespace AVA.Meeting.Client
{
    /// <summary>
    /// Text.xaml 的交互逻辑
    /// </summary>
    public partial class Text : Window
    {
        public Text()
        {
            InitializeComponent();
            this.DataContext = new TextViewModel();
        }
    }    class TextViewModel
    {
        public ICommand OnClosed { get; set; }        public TextViewModel()
        {
            this.OnClosed = new DelegateCommand<string>(str =>
            {
                MessageBox.Show("要关闭窗体了");
            }); 
        }
    }
}在我的windows的Closed绑定事件后,
运行程序点击Button按钮后并没有关闭窗体
这是因为Button的事件只是当作一个普通事件指行,
而点击窗体的“X”后,程序是先关闭了窗体后再触发当前事件,这地程序会卡住一会(因为报错报不出来,程序已经在关闭了。
问,那如何绑定一个后台事件给Windows
且触发这个命令后可以关闭窗体
谢谢

解决方案 »

  1.   

    OnClosed是关闭后触发的。
    使用OnClosing。
      

  2.   

    还是和 Set Focus 类似的问题。其实View 关闭不关闭,VM 不知道的。如果要在Button Command 里关闭的话,可以用 Application.Current.MainWindow.Close();之前你的错误是用Behavior处理Window Closed 然后再 MessageBox 这时候消息泵已经销毁。
    所以会有异常。建议退出处理还是在CodeBehind 里做。
      

  3.   

    也就是窗体的控制不在MVVM中处理?
    而MVVM只处理数据?
    我也这样做过,这样做的话在MVVM和窗口要进行交互的时候,总得声明事件来进行传递很是麻烦
    谢谢
      

  4.   

    如:CodeBehide里写Close事件的话,我有很多数据得去去ViewModel中去取和判断,而且页面会有事件会绑定关闭窗体的,这样这个事件又是声明在MVVM中,这样MVVM又要来调用CodeBehide中的Close事件
    这样感觉就是交差调用啊
    谢谢
      

  5.   

    我的意思退出动作由 View 发起。比如退出时还要做一些业务处理,那么可以在 Windows_Closing 时调用类似下面的处理,
    或者通过 Behavior 拦截窗体的 Closing 事件,交给Command处理。
    var vm = this.DataContext as XXXViewModel;
    if (vm != null) {
      vm.ExitCommand();
    }
      

  6.   

    问题是我现在我的要求是
    1:在关闭X时发起
    2:在窗体有按钮控件发起(这个按钮是MVVM的)
      

  7.   


    点击X发起,那么可以用behavior绑定closing事件到command上。
    如果是按钮点击,就在CodeBehind里调用this.Close()
    然后会触发closing事件,走上面的绑定。
      

  8.   

    楼上的方法也是我现在想的,但是还是不行的
    http://pan.baidu.com/share/link?shareid=117997&uk=3224032458
    上面是示例代码
    出现问题是:
    点X关闭正常
    点按钮只是执行事件,但不关闭
    如是如果在事件中添加this.Close()
    的话,点X,就会进行死循环,会多次执行我的OnClosed里面的内容(但程序是可以关掉的,我想是因为第一个Close的时候执行了,所以死循环也会退出)
    谢谢
      

  9.   

    为什么会死循环呢?(还是推荐使用下开源的Mvvmlight,就不用这么辛苦啦)下面的代码参考一下:
    我的意思是在Button_Click里调用this.Close();然后走窗体Closing EventTrigger 调用 VM 的 CloseCommand
    MainViewModel: (窗体关闭时通过 Behavior 拦截触发) private RelayCommand _closeCommand;
     public RelayCommand CloseCommand
     {
         get
         {
             if (_closeCommand == null)
             {
                 _closeCommand = new RelayCommand(() => {
                     Console.WriteLine("CloseCommand");
                 });
             }
             return _closeCommand;
         }
     }CodeBehind:MainWindow.xaml.cs public partial class MainWindow : Window
     {
         public MainWindow()
         {
             InitializeComponent();
         }     private void Button_Click_1(object sender, RoutedEventArgs e)
         {
             this.Close();
         }
     }Xmal
    <Window x:Class="MVVMClosingTest.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
            DataContext="{Binding Main, Source={StaticResource Locator}}"
            xmlns:gmc="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
            Title="MainWindow" Height="350" Width="525">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Closing">
                <gmc:EventToCommand PassEventArgsToCommand="True" Command="{Binding CloseCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <Grid>
            <Button Content="Button" HorizontalAlignment="Left" Margin="47,213,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>    </Grid>
    </Window>
      

  10.   

    是,根据你的方法把我原来的OnClosed拆分为OnClosed和OnTranForClosed
    现在可以了
    谢谢