事件源 sender source originalSource

本文通过实例解析了WPF中sender、source和originalsource的区别,并对比了路由事件与传统CLR事件的区别。

刚开始用WPF,总是搞不清三个事件源的关系,经过测试,终于有点明白了:

sender 事件的发送者 说白了就是谁调用的事件处理器

Source事件源 就是谁激发(raise)的事件 不使用路由事件的话 sender跟source是同一对象

OriginalSource 也是事件源 但他与Source不同的地方在于他是原始事件源,真正的激发事件的源头,当没有进行封装的时候,二者是同一对象

从下面这个例子中可以看出明显的区别

1.自定义控件

XAML
<UserControl x:Class="SourceTest.UserControl1"
             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="300" d:DesignWidth="300">
    <Grid>
        <StackPanel>
            <Button x:Name="testButton" Content="testButton" Click="testButton_Click" />
        </StackPanel>
    </Grid>
</UserControl>
CodeBehind
using System.Windows;
using System.Windows.Controls;

namespace SourceTest
{
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void testButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("sender Type:{0} \n\r source Type:{1} \n\r originalSource Type: {2}",
                sender.GetType().Name,e.Source.GetType().Name, e.OriginalSource.GetType().Name),"子窗体消息");
        }
    }
}

2.主窗体

XAML
<Window x:Class="SourceTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SourceTest"
        Title="MainWindow" Height="100" Width="200">
    <Grid>
        <local:UserControl1 x:Name="test1"/>
    </Grid>
</Window>
CodeBehind
using System.Windows;
using System.Windows.Controls;

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

            this.AddHandler(Button.ClickEvent, new RoutedEventHandler((s, e) => {
                MessageBox.Show(string.Format("sender Type:{0} \n\r source Type:{1} \n\r originalSource Type {2}",
                s.GetType().Name, e.Source.GetType().Name, e.OriginalSource.GetType().Name),"主窗体消息");
            }));
        }
    }
}

3.点击按钮 运行结果

 

这里多说一句,路由事件与传统CLR事件的区别在于,CLR事件的发送者是某个控件,响应者是某个事件处理器,发送者与响应者之间有个明显的订阅关系

路由事件的激发事件的对象跟处理事件的对象是分开的,源只负责激发事件,谁进行处理,他并不关系

转载于:https://www.cnblogs.com/goldren/archive/2012/12/28/2836861.html

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace _12._18._2 { public partial class Form1 : Form { private BindingSource bindingSource; // 存储图片路径的列表 private List<string> imagePaths; public Form1() { InitializeComponent(); InitBindingSource(); ShowCurrentImage(); } private void InitBindingSource() { // 初始化图片路径 imagePaths = new List<string>() { @"C:\Users\Administrator\Desktop\12.18\12.18.2\Resources\1.jpg", @"C:\Users\Administrator\Desktop\12.18\12.18.2\Resources\2.jpg", @"C:\Users\Administrator\Desktop\12.18\12.18.2\Resources\3 .jpg", @"C:\Users\Administrator\Desktop\12.18\12.18.2\Resources\4.jpg", }; // 初始化BindingSource并绑定数据源 bindingSource = new BindingSource(); bindingSource.DataSource = imagePaths; } private void ShowCurrentImage() { try { if (bindingSource.Current != null) { string currentPath = bindingSource.Current.ToString(); pictureBox1.Image = Image.FromFile(currentPath); pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; } } catch (Exception ex) { MessageBox.Show($"加载图片失败:{ex.Message}", "错误"); } } // 下一张按钮点击事件 private void btnNext_Click(object sender, EventArgs e) { } // 上一张按钮点击事件 private void button1_Click(object sender, EventArgs e) { // 移动到前一项,自动处理边界 if (bindingSource.Position > 0) { bindingSource.MovePrevious(); } else { bindingSource.Position = bindingSource.Count - 1; // 循环到最后一项 } ShowCurrentImage(); } private void button2_Click(object sender, EventArgs e) { // 移动到下一项,自动处理边界(到最后一项则不动) if (bindingSource.Position < bindingSource.Count - 1) { bindingSource.MoveNext(); } else { bindingSource.Position = 0; // 循环到第一项 } ShowCurrentImage(); } } }设置图片边距完善代码
最新发布
12-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值