WPF RoutedEvent and Command Sample
2011-08-12 12:10
225 查看
一直对WPF中的RoutedEvent和Command不太理解其原理,最近看了
ButtonBase.cs(http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/wpf/src/Framework/System/Windows/Controls/Primitives/ButtonBase@cs/1305600/ButtonBase@cs)
和Button.cs(http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/wpf/src/Framework/System/Windows/Controls/Button@cs/1458001/Button@cs)
源代码才逐渐明白一些,所以赶快写下来,以备后观。
比如我要写一个自己的Custom Control, 一个自己的Button,该Button不只有Click事件,同时还有自己定义的MyClick事件。那么如何定义和注册RoutedEvent呢,如下:
上面的步骤1就是我合并后的a,b两步。
然后就是编写自己的Button样式,并且使用该Button
样式:
使用之
详细代码如下
// MyButton.CS
/Theme/Generic.xaml
然后就是把他们绑在一起就可以了。 详细见
// MainWindow.xaml
ButtonBase.cs(http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/wpf/src/Framework/System/Windows/Controls/Primitives/ButtonBase@cs/1305600/ButtonBase@cs)
和Button.cs(http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/wpf/src/Framework/System/Windows/Controls/Button@cs/1458001/Button@cs)
源代码才逐渐明白一些,所以赶快写下来,以备后观。
编写自己的 RoutedEvent
要编写自己的RoutedEvent需要两大步骤,1是定义和注册RoutedEvent, 2是引发RoutedEvent。1、定义和注册RoutedEvent
需要三个步骤,a, definite your event. b, Register your event with EventManager. c, Wrap your event with traditional event wrapper(Property).比如我要写一个自己的Custom Control, 一个自己的Button,该Button不只有Click事件,同时还有自己定义的MyClick事件。那么如何定义和注册RoutedEvent呢,如下:
// 步骤1.要添加一个 RoutedEvent 首先要用EventManager注册一个 RoutedEvent public static readonly RoutedEvent MyClickEvent = EventManager.RegisterRoutedEvent( "MyClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButton)); // 步骤2.要定义一个Property 然后增加 对add/remove RoutedEventHandler的处理 public event RoutedEventHandler MyClick { add { base.AddHandler(MyButton.MyClickEvent, value); } remove { base.RemoveHandler(MyButton.MyClickEvent, value); } }
上面的步骤1就是我合并后的a,b两步。
2、引发RoutedEvent
要引发RoutedEvent, 需要处理更底层的Event事件,然后再Raise自己的RoutedEvent。我本来采用处理鼠标左键按下的事件来引发自定义的事件,但是好像屏蔽掉了Base的Click和Command处理。我想原因应该是没有处理左键弹起的事件。后来干脆OverRide ButtonBase.OnClick。// 3. 要通过对底层事件的处理引发自定义的事件。这里重写MouseDoubleClick //protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) //{ // //base.OnMouseLeftButtonDown(e); //base 的函数不起作用 Click 和 Command 都没有处理 // // new一个RoutedEventArgs // RoutedEventArgs re = new RoutedEventArgs(MyButton.MyClickEvent, this); // // Raise it. // base.RaiseEvent(re); // base.OnMouseLeftButtonDown(e); //} // 由于ButtonBase有virtual OnClick 会在OnMouseLeftButtonDown时被调用,可以重写此函数试一试 protected override void OnClick() { // 首先调用base的OnClick try { base.OnClick(); } finally { // new一个RoutedEventArgs RoutedEventArgs re = new RoutedEventArgs(MyButton.MyClickEvent, this); // // Raise it. base.RaiseEvent(re); } }//结果与设想的一样 引发Click,执行命令,并且处理MyClick.
然后就是编写自己的Button样式,并且使用该Button
样式:
<Style TargetType="{x:Type local:MyButton}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:MyButton}"> <Border Background="LightBlue" BorderBrush="Black" BorderThickness="1"> <ContentPresenter></ContentPresenter> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
使用之
<local:MyButton Click="Button_Click" Command="local:ExampleCommands.Requery" MyClick="MyButton_MyClick">My button</local:MyButton>
详细代码如下
// MyButton.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
namespace CommandAndEvent
{
/// <summary>
/// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
///
/// Step 1a) Using this custom control in a XAML file that exists in the current project.
/// Add this XmlNamespace attribute to the root element of the markup file where it is
/// to be used:
///
/// xmlns:MyNamespace="clr-namespace:CommandAndEvent"
///
///
/// Step 1b) Using this custom control in a XAML file that exists in a different project.
/// Add this XmlNamespace attribute to the root element of the markup file where it is
/// to be used:
///
/// xmlns:MyNamespace="clr-namespace:CommandAndEvent;assembly=CommandAndEvent"
///
/// You will also need to add a project reference from the project where the XAML file lives
/// to this project and Rebuild to avoid compilation errors:
///
/// Right click on the target project in the Solution Explorer and
/// "Add Reference"->"Projects"->[Browse to and select this project]
///
///
/// Step 2)
/// Go ahead and use your control in the XAML file.
///
/// <MyNamespace:MyButton/>
///
/// </summary>
public class MyButton : ButtonBase
{
static MyButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
}
// 1.要添加一个 RoutedEvent 首先要用EventManager注册一个 RoutedEvent
public static readonly RoutedEvent MyClickEvent = EventManager.RegisterRoutedEvent(
"MyClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButton));
// 2.要定义一个Property 然后增加 对add/remove RoutedEventHandler的处理
public event RoutedEventHandler MyClick
{
add
{
base.AddHandler(MyButton.MyClickEvent, value);
}
remove
{
base.RemoveHandler(MyButton.MyClickEvent, value);
}
}
// 3. 要通过对底层事件的处理引发自定义的事件。这里重写MouseDoubleClick //protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) //{ // //base.OnMouseLeftButtonDown(e); //base 的函数不起作用 Click 和 Command 都没有处理 // // new一个RoutedEventArgs // RoutedEventArgs re = new RoutedEventArgs(MyButton.MyClickEvent, this); // // Raise it. // base.RaiseEvent(re); // base.OnMouseLeftButtonDown(e); //} // 由于ButtonBase有virtual OnClick 会在OnMouseLeftButtonDown时被调用,可以重写此函数试一试 protected override void OnClick() { // 首先调用base的OnClick try { base.OnClick(); } finally { // new一个RoutedEventArgs RoutedEventArgs re = new RoutedEventArgs(MyButton.MyClickEvent, this); // // Raise it. base.RaiseEvent(re); } }//结果与设想的一样 引发Click,执行命令,并且处理MyClick.
}
}
/Theme/Generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CommandAndEvent"> <Style TargetType="{x:Type local:MyButton}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:MyButton}"> <Border Background="LightBlue" BorderBrush="Black" BorderThickness="1"> <ContentPresenter></ContentPresenter> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Command binding
实现命令的邦定,需要有命令源,只有实现了ICommandSouce的控件才能作为命令源,还好ButtonBase已经实现了,这里只要创建自己的RoutedCommand就可以了。与创建RoutedEvent类似:private static RoutedUICommand requery; static ExampleCommands() { InputGestureCollection inputs = new InputGestureCollection(); inputs.Add(new KeyGesture(Key.R, ModifierKeys.Control, "Ctr+R")); requery = new RoutedUICommand( "Requery text", "Requery name", typeof(ExampleCommands), inputs); } public static RoutedUICommand Requery { get { return requery; } }
然后就是把他们绑在一起就可以了。 详细见
// MainWindow.xaml
<Window x:Class="CommandAndEvent.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CommandAndEvent" Title="MainWindow" Height="350" Width="525"> <WrapPanel> <Button Click="Button_Click" Command="local:ExampleCommands.Requery"> Click Me </Button> <local:MyButton Click="Button_Click" Command="local:ExampleCommands.Requery" MyClick="MyButton_MyClick">My button</local:MyButton> </WrapPanel> <Window.CommandBindings> <CommandBinding Command="local:ExampleCommands.Requery" CanExecute="Requery_CanExecute" Executed="Requery_Executed" /> </Window.CommandBindings> </Window>
相关文章推荐
- Routed event and command
- Pro WPF and Silverlight MVVM:第5章 Event and Command 读书笔记
- 将WPF中控件的Event转换成Command执行(转)
- WPF的自定义控件 依赖属性,DependencyProperty 路由事件RoutedEvent
- WPF ICommand RoutedCommand
- WPF入门(二):初遇RoutedEvent
- WPF中控件的Event转换成Command执行(转)
- Gridview之RowCommand,ButtonField[add buttons and use the RowCommand event to add custom functionality to the control]
- WPF 路由事件(RoutedEventArgs 事件消息、 RoutedEvent 路由事件、RoutedEventHandler路由事件处理程序、RaiseEvent引发路由事件)
- WPF: RoutedEvent
- 将WPF中控件的Event转换成Command执行
- 转载:WPF Routed Commands: Overview and Examples
- WPF使用RoutedCommand自己定义命令
- WPF使用RoutedCommand自定义命令
- unix find command tutorial and sample code
- WPF--event、delegate、EventHandler、RoutedEventHandler的区别
- WPF: RoutedEvent
- WPF入门(二):初遇RoutedEvent
- WPF中简单的EventToCommand
- WPF自定义RoutedEvent事件代码段