WPF学习之路(四)路由_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > WPF学习之路(四)路由

WPF学习之路(四)路由

 2015/4/16 18:31:12  alex_cool  程序员俱乐部  我要评论(0)
  • 摘要:路由事件概述功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。实现定义:路由事件是一个CLR事件,可以由RouteEvent类的实例提供支持并由WindowsPresentationFoundation(WPF)事件系统来处理。实例:Xaml<BorderHeight="50"Width="300"BorderBrush="Gray"BorderThickness="1"><
  • 标签:学习

路由事件概述

功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。

实现定义:路由事件是一个 CLR 事件,可以由RouteEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理。

 

实例:

Xaml

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
  <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
    <Button Name="YesButton" Width="Auto" >Yes</Button>
    <Button Name="NoButton" Width="Auto" >No</Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>
  </StackPanel>
</Border>

class="sentence" data-guid="c5ddc1060b7fdbb103762a142fb97d2d" data-source="In this simplified element tree, the source of a <span class="mtpsTagOuterHtml" >Click event is one of the <span class="mtpsTagOuterHtml" >Button elements, and whichever <span class="mtpsTagOuterHtml" >Button was clicked is the first element that has the opportunity to handle the event.">在这个简化的元素树中,Click事件的源是某个 Button元素,而所单击的 Button是有机会处理该事件的第一个元素。 但是,如果附加到 Button的任何处理程序均未作用于该事件,则该事件将向上冒泡到元素树中的 Button父级(即 StackPanel)。 该事件可能会冒泡到 Border,然后会到达元素树的页面根(未显示出来)。

换言之,此Click事件的事件路由为:Button-->StackPanel-->Border-->...

 

路由事件的策略

Bubbling:路由事件随后会路由到后续的父元素,直到到达元素树的根。 

Direct:只有源元素本身才有机会调用处理程序以进行响应

Tunneling:最初将在元素树的根处调用事件处理程序。

路由事件策略会因为一下因素改变:

 

事件处理函数

public delegate void RoutedEventHandler(Object Sender, RoutedEventArgs e);
public delegate void MouseEventHandler(Object Sender, MouseEventArgs e);

RoutedEventArgs和MouseEventArgs包含路由事件的信息

如果设置"Handled"属性为True,路由事件会停止传递

 

类和实例事件处理函数

事件处理函数有两种类型,前一种是普通事件处理函数,"实例事件处理函数",另一种是通过EventManager.RegisterClassHandler方法将一个事件处理函数和类关联起来,"类事件处理函数",优先级更高

 

 

实例:(取自《葵花宝典--WPF自学手册》6.5)

自定义Button类

public class MySimpleButton : Button
{
    static MySimpleButton()
    {
        EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);
    }

    public event EventHandler ClassHandlerProcessed;
    public static void CustomClickClassHandler(Object sender, RoutedEventArgs e)
    {
        MySimpleButton simpBtn = sender as MySimpleButton;
        EventArgs args = new EventArgs();
        simpBtn.ClassHandlerProcessed(simpBtn, e);
    }

    //Create and register routed event, routing strategies: Bubble
    public static readonly RoutedEvent CustomClickEvent = EventManager.RegisterRoutedEvent(
        "CustomClick",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(MySimpleButton));

    //CLR event wrapper
    public event RoutedEventHandler CustomClick
    {
        add { AddHandler(CustomClickEvent, value); }
        remove { RemoveHandler(CustomClickEvent, value); }
    }

    //Raise CustomClickEvent
    void RaiseCustomClickEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(MySimpleButton.CustomClickEvent);
        RaiseEvent(newEventArgs);
    }

    //Onclick
    protected override void OnClick()
    {
        RaiseCustomClickEvent();
    }

}

 

MainWindow.xaml

<Window x:Class="Alex_WPFAPPDemo02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom="clr-namespace:Alex_WPFAPPDemo02"
        custom:MySimpleButton.CustomClick="InsertList"
        Title="MainWindow" Height="350" Width="525">
    <Grid Margin="3" custom:MySimpleButton.CustomClick="InsertList" Name="Grid1">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <custom:MySimpleButton x:Name="simpBtn" CustomClick="InsertList">
            My Simple Button
        </custom:MySimpleButton>
        <ListBox Margin="5" Name="listBox" Grid.Row="1" />
        <CheckBox Margin="5" Grid.Row="2" Name="chkHandle">
            Handle first event
        </CheckBox>
        <Button Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3" Click="clear">
            Clear List
        </Button>
    </Grid>
</Window>

 

MainWindow.xaml.cs

protected int eventCounter = 0;
private void InsertList(object sender, RoutedEventArgs e)
{
    eventCounter++;
    string message = "#" + eventCounter.ToString() + ":\r\n"
        + "InsertList\r\n"
        + " Sender: " + sender.ToString() + "\r\n"
        + " Source: " + e.Source + "\r\n"
        + "Original Source: " + e.OriginalSource;
    listBox.Items.Add(message);
    e.Handled = (bool)chkHandle.IsChecked;
}

private void clear(object sender, RoutedEventArgs e)
{
    eventCounter = 0;
    listBox.Items.Clear();
}

 

添加类处理函数

static MySimpleButton()
{
    EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);
}

public event EventHandler ClassHandlerProcessed;
public static void CustomClickClassHandler(Object sender, RoutedEventArgs e)
{
    MySimpleButton simpBtn = sender as MySimpleButton;
    EventArgs args = new EventArgs();
    simpBtn.ClassHandlerProcessed(simpBtn, e);
}

 

完善代码

public MainWindow()
{
    InitializeComponent();
    this.simpBtn.ClassHandlerProcessed += new EventHandler(ButtonRaisedClass);
}private void ButtonRaisedClass(object sender, EventArgs e)
{
    eventCounter++;
    string message = "#" + eventCounter.ToString() + ":\r\n"
        + "Windows Class Handler\r\n"
        + " Sender: " + sender.ToString();
    listBox.Items.Add(message);
}

private void ProcessHanldersToo(Object sender, RoutedEventArgs e)
{
    eventCounter++;
    string message = "#" + eventCounter.ToString() + ":\r\n"
        + "ProcessHanldersToo\r\n"
        + " Sender: " + sender.ToString()
        + " Source: " + e.Source + "\r\n"
        + "Original Source: " + e.OriginalSource;
    listBox.Items.Add(message);
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Grid1.AddHandler(MySimpleButton.CustomClickEvent, new RoutedEventHandler(ProcessHanldersToo), true);
}

 

 可以查看路由事件的线路

 

 

 

 

 

 

To be continue...

发表评论
用户名: 匿名