Levon Chen 的脚步

生活在于拥抱改变。

WPF中控件的Event转换成Command执行

信息收集:

 

http://www.cnblogs.com/Code-life/archive/2010/12/05/1897206.html

http://blogs.msdn.com/b/devdave/archive/2008/06/22/using-an-attached-dependencyproperty-to-implement-pixel-snapping-as-an-attached-behavior.aspx

 

详细实现。

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Reflection;

namespace TestAutoGenerateColumnForGridView
{
 public static class CommandBindingBehavior
 {
  public static DependencyProperty BindingEventNameProperty = DependencyProperty.RegisterAttached
   ("BindingEventName", typeof(string),
   typeof(CommandBindingBehavior), new PropertyMetadata(null, OnBindingEventChanged));

  public static string GetBindingEventName(DependencyObject obj)
  {
   return (string)obj.GetValue(BindingEventNameProperty);
  }

  public static void SetBindingEventName(DependencyObject obj, string value)
  {
   obj.SetValue(BindingEventNameProperty, value);
  }

  public static DependencyProperty BindingCommandProperty = DependencyProperty.RegisterAttached
   ("BindingCommand", typeof(ICommand), typeof(CommandBindingBehavior), new PropertyMetadata(null));

  public static ICommand GetBindingCommand(DependencyObject obj)
  {
   object com = obj.GetValue(BindingCommandProperty);
   if (com == null)
    return null;

   return (ICommand)com;
  }

  public static void SetBindingCommand(DependencyObject obj, ICommand value)
  {
   obj.SetValue(BindingCommandProperty, value);
  }

  private static void OnEventRaised<T>(object sender, T arg) where T: EventArgs
  {
   DependencyObject dependencyObject = sender as DependencyObject;
   if (dependencyObject != null)
   {
    ICommand command = GetBindingCommand(dependencyObject);
    if (command != null)
    {
     if (command.CanExecute(arg))
     {
      command.Execute(arg);
     }
    }
   }
  }

  private static void OnBindingEventChanged(DependencyObject sender, DependencyPropertyChangedEventArgs arg)
  {
   Type senderType = sender.GetType();
   EventInfo eventInfo = senderType.GetEvent(arg.NewValue.ToString());
   eventInfo.AddEventHandler(sender, GenerateDelegateForEventHandler(eventInfo));
  }


  private static Delegate GenerateDelegateForEventHandler(EventInfo eventInfo)
  {
   Delegate result = null;

   MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");
   ParameterInfo[] parameters = methodInfo.GetParameters();
   if (parameters.Length == 2)
   {
    Type currentType = typeof(CommandBindingBehavior);
    Type argType = parameters[1].ParameterType;
    MethodInfo eventRaisedMethod =
    currentType.GetMethod("OnEventRaised", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(argType);
    result = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventRaisedMethod);
   }

   return result;
  }

 }
}

 

 

使用:

        <ListView ItemsSource ="{Binding Persons}" ItemContainerStyle="{StaticResource ResourceKey=ListViewItemStyle}"                 
                  local:CommandBindingBehavior.BindingCommand ="{Binding Path=NewFolderCommand}"
                  local:CommandBindingBehavior.BindingEventName="MouseUp">
            <ListView.View>
            </ListView.View>
        </ListView>

ModelView:

 

 

/// <summary>
 /// Interaction logic for MainWindow.xaml
 /// </summary>
 public partial class MainWindow : Window
 {

  Lazy<RelayCommand> mNewFolderCommand;

  public MainWindow()
  {
   InitializeComponent();
   this.DataContext = this;

   //new folder command
   mNewFolderCommand = new Lazy<RelayCommand>(() => new RelayCommand(NewFolderCommandExecuted, NewFolderCommandCanExecute));
  }
  #region NewFolderCommand

  /// <summary>
  /// Up command
  /// </summary>
  public ICommand NewFolderCommand
  {
   get { return mNewFolderCommand.Value; }
  }

  /// <summary>
  /// Executes the Up command
  /// </summary>
  private void NewFolderCommandExecuted()
  {

  }

  private bool NewFolderCommandCanExecute()
  {
   return true;
  }
  #endregion
 }

 

依赖于:

MvvMFoudation: http://wpf.codeplex.com/

中的RelayCommand

具体实现:

 

namespace TestAutoGenerateColumnForGridView
{
 /// <summary>
 /// A command whose sole purpose is to
 /// relay its functionality to other
 /// objects by invoking delegates. The
 /// default return value for the CanExecute
 /// method is 'true'.
 /// </summary>
 public class RelayCommand<T> : ICommand
 {
  readonly Action<T> _execute;
  readonly Predicate<T> _canExecute;

  public RelayCommand(Action<T> execute)
   : this(execute, null)
  {
  }

  /// <summary>
  /// Creates a new command.
  /// </summary>
  /// <param name="execute">The execution logic.</param>
  /// <param name="canExecute">The execution status logic.</param>
  public RelayCommand(Action<T> execute, Predicate<T> canExecute)
  {
   if (execute == null)
    throw new ArgumentNullException("execute");

   _execute = execute;
   _canExecute = canExecute;
  }

  #region ICommand Members

  [DebuggerStepThrough]
  public bool CanExecute(object parameter)
  {
   return _canExecute == null ? true : _canExecute((T)parameter);
  }

  public event EventHandler CanExecuteChanged
  {
   add
   {
    if (_canExecute != null)
     CommandManager.RequerySuggested += value;
   }
   remove
   {
    if (_canExecute != null)
     CommandManager.RequerySuggested -= value;
   }
  }

  public void Execute(object parameter)
  {
   _execute((T)parameter);
  }

  #endregion // ICommand Members
 }

 /// <summary>
 /// A command whose sole purpose is to
 /// relay its functionality to other
 /// objects by invoking delegates. The
 /// default return value for the CanExecute
 /// method is 'true'.
 /// </summary>
 public class RelayCommand : ICommand
 {
  readonly Action _execute;
  readonly Func<bool> _canExecute;
  
  /// <summary>
  /// Creates a new command that can always execute.
  /// </summary>
  /// <param name="execute">The execution logic.</param>
  public RelayCommand(Action execute)
   : this(execute, null)
  {
  }

  /// <summary>
  /// Creates a new command.
  /// </summary>
  /// <param name="execute">The execution logic.</param>
  /// <param name="canExecute">The execution status logic.</param>
  public RelayCommand(Action execute, Func<bool> canExecute)
  {
   if (execute == null)
    throw new ArgumentNullException("execute");

   _execute = execute;
   _canExecute = canExecute;
  }

  #region ICommand Members

  [DebuggerStepThrough]
  public bool CanExecute(object parameter)
  {
   return _canExecute == null ? true : _canExecute();
  }

  public event EventHandler CanExecuteChanged
  {
   add
   {
    if (_canExecute != null)
     CommandManager.RequerySuggested += value;
   }
   remove
   {
    if (_canExecute != null)
     CommandManager.RequerySuggested -= value;
   }
  }

  public void Execute(object parameter)
  {
   _execute();
  }

  #endregion // ICommand Members
 }
}

 

 

 

posted on 2010-12-22 13:06  Levon Chen  阅读(639)  评论(0编辑  收藏  举报

导航