如何在DataTemplate中处理事件Events
来源:互联网 发布:奇热漫画软件 编辑:程序博客网 时间:2024/05/16 14:17
文章摘自 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>
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
- 如何在DataTemplate中处理事件Events
- android 在ViewGroup中处理触摸事件 [Managing Touch Events in a ViewGroup]
- 如何在SPFILE中设置EVENTS
- WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探
- Events (Delphi)Delphi中事件
- 如何在VS2005中自动添加事件处理函数?
- 如何在VS2005中自动添加事件处理函数?
- 如何在VS2005中自动添加事件处理函数?
- 如何在VS2005中自动添加事件处理函数?
- 如何在abap中为ALV添加事件处理
- 如何解决在服务中处理activity中的事件
- 如何优雅地在React中处理事件响应
- Nodejs学习 2 -- events事件处理EventEmitter
- WPF中如何使用C#创建DataTemplate数据模版
- 在C#中处理事件
- 在C#中处理事件
- events 事件
- DataTemplate
- Qt中int转换成QString
- 发动机转速和曲轴位置传感器作用、安装及类型
- 黑苦荞茶真的有那么好吗
- 早该写点东西
- 微信公众平台开发(二) 微信公众平台示例代码分析
- 如何在DataTemplate中处理事件Events
- 数据包接收系列 — IP协议处理流程(二)
- POJ 2096 Collecting Bugs (概率dp)
- 搭建Red5流媒体服务
- 第六周项目2-对象作为数据成员
- LUCI架构
- linux ioctl()函数
- 第三周-5
- OK6410下运行Qt程序glibc问题