如有:
<Window x:Class="AVA.Meeting.Client.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="900" Width="800" MinWidth="800" MinHeight="500" Closed="{Binding OnClose}">
有CS        public ICommand OnClose { get; set; }        public void Close(string paranper)
        {
            if (Service.ServiceClient.Instance != null)
            {
                Service.ServiceClient.Instance.Leave();
                Service.ServiceClient.Instance.Close();
                Service.ServiceClient.Instance = null;
            }
            //this.window.Close();
        }
但绑定运行后出错:
在“System.Windows.Data.Binding”上提供值时引发了异常。”
{"无法将类型为“System.Reflection.RuntimeEventInfo”的对象强制转换为类型“System.Reflection.MethodInfo”。"}

解决方案 »

  1.   

    Closed是事件不能绑定,还是要用触发器来实现:<Window x:Class="AVA.Meeting.Client.View.MainWindow"
            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"
            Height="900" Width="800" MinWidth="800" MinHeight="500">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Closed">
                <i:InvokeCommandAction Command="{Binding OnClose}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        ... ...如果需要这样处理事件的地方很多的话,都像上面这样写xaml就会比较繁复。所以不如干脆直接在code behind类里写事件处理方法,让xaml看上去简单些。比如: public MainWindow()
    {
    this.DataContext = new ViewModel.MainWindowViewModel(this);
    InitializeComponent();
    this.Closed += (o, args) => ((MainWindowViewModel) DataContext).OnClose.Execute(null);
    }我知道网上有些人主张code behind类应该是"0代码"。虽然我个人觉得没必要这么教条,不过如果你不想在code behind类里写代码的话,也可以写一个attached property来简化执行事件命令的xaml标记写法。
    attached property的写法我在前一个帖子写过:http://bbs.csdn.net/topics/390271219
    把里面的CommandAction类KeyDown相关的部分改成Closed,就能把它变成在Closed事件触发时执行command命令。上面帖子里的这个方法还可以进一步改进成通用的基类,方便任意事件对其进行扩展使用: public class EventCommand<T> where T:EventCommand<T>, new()
    {
    public static DependencyProperty CommandProperty =
    DependencyProperty.RegisterAttached("Command", typeof (ICommand), typeof (EventCommand<T>),
                                        new UIPropertyMetadata(OnCommandChanged)); private static Action<UIElement> _addHandler;
    private static Action<UIElement> _removeHandler; public static void Register<TOwner>(Action<TOwner> addHandler, Action<TOwner> removeHandler)
    where TOwner : UIElement
    {
    _addHandler = x=> addHandler((TOwner)x);
    _removeHandler = x => removeHandler((TOwner)x);
    } public static void Register(RoutedEvent @event, Func<Delegate> handler = null)
    {
    handler = handler ?? (()=>new RoutedEventHandler(InvokeCommand));
    _addHandler = x => x.AddHandler(@event, handler());
    _removeHandler = x=> x.RemoveHandler(@event, handler());
    } public static void SetCommand(UIElement target, ICommand value)
    {
    target.SetValue(CommandProperty, value);
    } private static T _me;
    private static void OnCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
    if (_me == null) _me = new T(); // ensure event and handlers are registered
    var element = target as UIElement;
    if (element == null)
    throw new InvalidOperationException("This behavior can be attached to ui element only.");
    if (e.NewValue != null && e.OldValue == null)
    _addHandler(element);
    else if (e.NewValue == null && e.OldValue != null)
    _removeHandler(element);
    } protected static void InvokeCommand(object sender, EventArgs e)
    {
    var command = (ICommand) ((FrameworkElement)sender).GetValue(CommandProperty);
    command.Execute(e);
    }
    } public class KeyDown : EventCommand<KeyDown> { static KeyDown() { Register(UIElement.KeyDownEvent); }}
    public class KeyUp : EventCommand<KeyUp> { static KeyUp() { Register(UIElement.KeyUpEvent); }}
    public class GotFocus : EventCommand<GotFocus> { static GotFocus() { Register(UIElement.GotFocusEvent); }}
    public class LostFocus : EventCommand<LostFocus> { static LostFocus() { Register(UIElement.LostFocusEvent); }}
    public class Closed : EventCommand<Closed> {
    static Closed() { Register<Window>(x=>x.Closed+=InvokeCommand, x=>x.Closed-=InvokeCommand); }
    }EventCommand就是和上面帖子里差不多的附加属性类,下面的KeyDown,KeyUp,GotFocus,LostFocus这些派生子类具体定义了事件类型和处理方式。按照上面的写法可以很方便地再添加其它种类的事件。
    前台用法:<Window x:Class="AVA.Meeting.Client.View.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:AVA.Meeting.SomeUtilityNameSpace"
            local:Closed.Command="{Binding OnClose}"
            Height="900" Width="800" MinWidth="800" MinHeight="500">
    或者比如:
        <TextBox local:KeyDown.Command="{Binding OnKeyDown}" 
                local:GotFocus.Command="{Binding OnGotFocus}" 
                local:LostFocus.Command="{Binding OnLostFocus}"> 
    注意这样执行的命令是传递事件参数的,所以你的OnClose命令不能是string参数类型,在你的BindEvent方法里要写成:this.OnClose = new DelegateCommand<EventArgs>(Close);