码迷,mamicode.com
首页 > Windows程序 > 详细

深入浅出WPF--笔记(2015.03.21)

时间:2015-03-22 06:59:05      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:wpf routedevent

    RoutedEventArgs有两个属性:OriginalSource和Source,这两个属性都表示路由事件传递的起点(即事件消息的源头),OriginalSource表示VisualTree上的源头,而Source表示的是LogicalTree上的消息源头。事例如下:

XAML代码:

<UserControl x:Class="MyTest.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="80" d:DesignWidth="80">
    <Border BorderBrush="Orange" BorderThickness="3" CornerRadius="5">
        <Button x:Name="innerButton" Width="80" Height="80" Content="OK"/>
    </Border>
</UserControl>

    <Grid>
        <local:MyUserControl x:Name="myUserControl" Margin="10"/>
    </Grid>

C#代码:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.Button_Click));
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            string strOrigialSource = string.Format("VisualTree start point: {0}, type is {1}.", (e.OriginalSource as FrameworkElement).Name, e.OriginalSource.GetType().Name);
            string strSource = string.Format("LogicalTree start point: {0}, type is {1}.", (e.Source as FrameworkElement).Name, e.Source.GetType().Name);
            MessageBox.Show(strOrigialSource + "\r\n" + strSource);
        }
    }

    在WPF事件系统中还有一种事件被称为附加事件(Attached Event),本质就是路由事件。路由事件的宿主都是些拥有可视化实体的界面元素,而附加事件则不具备显示在用户界面上的能力。也就是说,附加事件的宿主没有界面渲染功能,但可以使用附加事件与其他对象进行沟通。实例如下:

XAML代码:

    <Grid x:Name="gridMain">
        <Button x:Name="button1" Content="OK" Width="80" Height="80" Click="Button_Click"/>
    </Grid>

C#代码:

    public class Student
    {
        public static readonly RoutedEvent NameChangedEvent = EventManager.RegisterRoutedEvent("NameChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Student));
        public int Id { get; set; }
        public string Name { get; set; }
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.gridMain.AddHandler(Student.NameChangedEvent, new RoutedEventHandler(this.NameChangedEventHandler));
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Student stu = new Student { Id = 101, Name = "Tom" };
            stu.Name = "Tim";
            RoutedEventArgs args = new RoutedEventArgs(Student.NameChangedEvent, stu);
            this.button1.RaiseEvent(args);
        }

        private void NameChangedEventHandler(object sender, RoutedEventArgs e)
        {
            MessageBox.Show((e.OriginalSource as Student).Id.ToString());
        }
    }

为附加事件添加CLR包装器时,微软规定:

(1)、为目标UI元素添加附加事件侦听器的包装器是一个名为Add*Handler的public static方法,星号代表事件名称。此方法接收两个参数,第一个是事件的侦听者(类型为DependencyObject),第二个参数为事件的处理器(RoutedEventHandler委托类型);

(2)、解除UI元素对附加事件侦听器的包装器是名为Remove*Handler的public static方法,星号亦为事件名称,参数与Add*Handler一致。事例如下:

XAML代码:

    <Grid x:Name="gridMain">
        <Button x:Name="button1" Content="OK" Width="80" Height="80" Click="Button_Click"/>
    </Grid>

C#代码:

    public class Student
    {
        public static readonly RoutedEvent NameChangedEvent = EventManager.RegisterRoutedEvent("NameChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Student));

        public static void AddNameChangedEventHandler(DependencyObject d, RoutedEventHandler r)
        {
            UIElement e = d as UIElement;
            if (null != e)
                e.AddHandler(Student.NameChangedEvent, r);
        }

        public static void RemoveNameChangedEventHandler(DependencyObject d, RoutedEventHandler r)
        {
            UIElement e = d as UIElement;
            if (null != e)
                e.RemoveHandler(Student.NameChangedEvent, r);
        }

        public int Id { get; set; }
        public string Name { get; set; }
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            //this.gridMain.AddHandler(Student.NameChangedEvent, new RoutedEventHandler(this.NameChangedEventHandler));
            Student.AddNameChangedEventHandler(this.gridMain, new RoutedEventHandler(this.NameChangedEventHandler));
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Student stu = new Student { Id = 101, Name = "Tom" };
            stu.Name = "Tim";
            RoutedEventArgs args = new RoutedEventArgs(Student.NameChangedEvent, stu);
            this.button1.RaiseEvent(args);
        }

        private void NameChangedEventHandler(object sender, RoutedEventArgs e)
        {
            MessageBox.Show((e.OriginalSource as Student).Id.ToString());
        }
    }

UIElement类是路由事件宿主与附加事件宿主的分水岭。如果在一个非UIElement派生类中注册了路由事件,则这个类的实例既不能自己激发(Raise)此路由事件,也无法自己侦听此路由事件,只能把这个事件的激发"附着"在某个具有RaiseEvent方法的对象上,借助此对象的RaiseEvent方法把事件发送出去;事件的侦听任务也只能交给别的对象去做。

本文出自 “墨池小样儿” 博客,请务必保留此出处http://306702895.blog.51cto.com/8366753/1622876

深入浅出WPF--笔记(2015.03.21)

标签:wpf routedevent

原文地址:http://306702895.blog.51cto.com/8366753/1622876

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!