如何在DataTemplate中处理事件Events

文章摘自 Naveen Dhaka's blog

http://nerobrain.blogspot.nl/2012/01/wpf-events-to-command.html


Tuesday, January 10, 2012

Wire any WPF Event to Command on ViewModel in MVVM

In the last post I explained how to write a behaviour to hook a commmand to an event. That works well but a new behaviour is needed to written for each event. I tried a generic approach to have a single behaviour that can be used to wire any event to a command. It comes witha little performance penalty as reflection is used to get the event and attached a delegate to that event. Below is the code:

using  System.Windows.Input;
using  System.Windows.Controls.Primitives;
using  System.Windows.Controls;
using  System.Reflection;
using  System.Diagnostics;

public   class   CommandExecuter
{
public   static   readonly   DependencyProperty  CommandProperty = DependencyProperty .RegisterAttached( "Command" typeof ( ICommand ), typeof ( CommandExecuter ),  new   PropertyMetadata (CommandPropertyChangedCallback));
 
public   static   readonly   DependencyProperty  OnEventProperty = DependencyProperty .RegisterAttached( "OnEvent" typeof ( string ), typeof ( CommandExecuter ));
 
public   static   readonly   DependencyProperty  CommandParameterProperty = DependencyProperty .RegisterAttached( "CommandParameter" typeof ( object ), typeof ( CommandExecuter ));

public   static   void  CommandPropertyChangedCallback( DependencyObject  depObj, DependencyPropertyChangedEventArgs  args)
{
  string  onEvent = ( string )depObj.GetValue(OnEventProperty);
  Debug .Assert(onEvent !=  null "OnEvent must be set." );
  var  eventInfo = depObj.GetType().GetEvent(onEvent);
  if  (eventInfo !=  null )
  {
    var  mInfo =  typeof ( CommandExecuter ).GetMethod( "OnRoutedEvent" , BindingFlags .NonPublic |  BindingFlags .Static);
    eventInfo.GetAddMethod().Invoke(depObj,  new   object [] { Delegate .CreateDelegate(eventInfo.EventHandlerType, mInfo) });
  }
  else
  {
    Debug .Fail( string .Format( "{0} is not found on object {1}" , onEvent, depObj.GetType()));
 
}

}
public   static   ICommand  GetCommand( UIElement  element)
{
   return  ( ICommand )element.GetValue(CommandProperty);
}
public   static   void  SetCommand( UIElement  element,  ICommand  command)
{
   element.SetValue(CommandProperty, command);
}
public   static   string  GetOnEvent( UIElement  element)
{
return  ( string )element.GetValue(OnEventProperty);
}
public   static   void  SetOnEvent( UIElement  element,  string  evnt)
{
   element.SetValue(OnEventProperty, evnt);
}
public   static   object  GetCommandParameter( UIElement  element)
{
  return  ( object )element.GetValue(CommandParameterProperty);
}
public   static   void  SetCommandParameter( UIElement  element,  object  commandParam)
{
   element.SetValue(CommandParameterProperty, commandParam);
}
private   static   void  OnRoutedEvent( object  sender,  RoutedEventArgs  e)
{
  UIElement  element = ( UIElement )sender;
  if  (element !=  null )
  {     ICommand  command = element.GetValue(CommandProperty)  as   ICommand ;
    if  (command !=  null &&command.CanExecute(element.GetValue(CommandParameterProperty)) )
    {
      command.Execute(element.GetValue(CommandParameterProperty));
    }
  }
}
}

Below code shows how to set the command on the controls for any event:   (local: is namespace prefix)
< ComboBox  local: CommandExecuter.Command = " {Binding CommandImpl} " local:CommandExecuter.OnEvent = " SelectionChanged "  ></ComboBox>

<Button local:CommandExecuter.Command="{Binding AnotherCommandImpl}"local:CommandExecuter.OnEvent="MouseEnter"local:CommandExecuter.CommandParameter="{x:Static null}"></Button>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值