路由事件
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了路由事件相关的知识,希望对你有一定的参考价值。
原文:路由事件简介:每个.NET开发人员都熟悉"事件"的思想,当有意义的事情发生时,由对象(WPF元素)发送的用于通知代码的消息。WPF通过路由(event routing)的概念增强了.Net事件模型,事件路由允许源自某个元素的事件由另一个元素引发。
1、定义、注册和封装路由事件。
步骤:
1.1)、由只读的、静态的方式声明。
1.2)、在静态的构造函数中通过EventManager.RegisterRoutedEvent()方法注册。
1.3)、通过.Net事件定义进行封装。
例子:
public class ButtonBase:ContentControl
{
//声明只读的、静态的、RoutedEvent类型的字段。
public static readonly RoutedEvent ClickEvent;
/// <summary>
/// 在静态的构造函数中注册路由事件。
/// </summary>
static ButtonBase()
{
//路由事件是使用EventManager.RegisterRoutedEvent()方法注册的。
//参数:Click:事件的名称。
//参数:RoutingStrategy.Bubble:路由的类型(冒泡路由、隧道路由)。
//参数:typeof(RoutedEventHandler):定义事件处理程序语法的委托。
//参数:typeof(ButtonBase):拥有事件的类。
ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));
}
//通过普通的.Net事件进行封装,从而使所有的.Net语言都能访问他,事件封装器可使用AddHandle()和RemoveHandle()方法添加删除已注册的程序。
public event RoutedEventHandler Click
{
add
{
//为指定的路由事件添加路由事件处理程序,并将该处理程序添加到当前元素的处理程序集合中。
base.AddHandler(ClickEvent, value);
}
remove
{
//从此元素移除指定的路由事件处理程序。
base.RemoveHandler(ClickEvent, value);
}
}
}
2、共享路由事件。
与依赖项属性一样,可在类之间共享路由事件的定义,例如,UIElement(该类是所有普通WPF元素的起点),MouseUp事件是由System.WIndows.Input.Mouse类定义的,UIElement类和ContentElement类只通过Routed-Event.AddOwner()方法重用MouseUp事件。
UIElemtn.MouseUpEvent = Mouse.MouseUpEvent.AddOwner(typeof(UIElement));
3、处理路由事件。
3.1)、Xaml的方式添加处理程序。
Xaml代码:
<Grid>
<Image Name="img1" Source="Images/1.jpg" MouseEnter="Image_MouseEnter"></Image>
</Grid>
Image_MouseEnter处理函数:
private void Image_MouseEnter(object sender, MouseEventArgs e)
{
MessageBox.Show("MouseEnter事件");
}
3.2)、通过+=使用代码链接。
创建了一个针对该事件具有正确签名的委托对象(该类中是MouseEventHandler委托的实例),并将该委托指向Img_MouseEnter()方法。然后将该委托添加到img1.MouseEnter事件的已注册的事件的处理程序列表中。
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//第一种写法。
img1.MouseEnter += new MouseEventHandler(Img_MouseEnter);
//第二种写法。
img1.MouseEnter += Img_MouseEnter;
}
private void Img_MouseEnter(object sender, MouseEventArgs e)
{
MessageBox.Show("进入了MouseEnter事件");
}
3.3)、通过AddHandler()方法添加事件处理程序。
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//Image.MouseEnterEvent:处理路由事件的标志符。
//new MouseEventHandler(Img_MouseEnter):处理程序实现的引用。
img1.AddHandler(Image.MouseEnterEvent, new MouseEventHandler(Img_MouseEnter));
}
private void Img_MouseEnter(object sender, MouseEventArgs e)
{
MessageBox.Show("进入了MouseEnter事件");
}
4、断开事件处理程序。
4.1)、通过-=断开事件处理程序。
//第一种写法。
img1.MouseEnter -= new MouseEventHandler(Img_MouseEnter);
//第二种写法。
img1.MouseEnter -= Img_MouseEnter;
4.2)、通过RemoveHandler()方法断开事件处理程序。
img1.RemoveHandler(Image.MouseEnterEvent, new MouseEventHandler(Img_MouseEnter));
5、事件路由。
WPF中,事件路由以3种方式出现:直接路由事件(Direct event)、冒泡路由事件(bubbing event)、隧道路由事件(tunneling)。
在WPF中,如果事件不需要传递任何额外细节,可使用RoutedEventArgs类,该类包含了一些有关如何传递事件的一些细节,如果事件确实需要传递一些额外的信息,那么需要使用更特殊的继承自RoutedEventArgs的对象,其中每个WPF事件参数类都继承自RoutedEventArgs类。
RoutedEventArgs类常用属性 |
|
Source |
指示引发事件的对象。 |
OriginalSource |
指示最初是什么对象引发了事件。 |
RoutedEvent |
通过事件处理程序为触发的事件提供RoutedEvent对象,如果同一个事件处理程序处理不同的事件,这一信息是非常有用的。 |
Handled |
该属性允许终止事件的冒泡或隧道过程,如果将该属性设置为true,就终止了传递。 |
5.1)、直接路由。
源于同一个元素,不传递给其他。如元素的MouseEnter事件。
5.2)、冒泡路由。
从下到上传递。一般情况下,冒泡路由以Mouse开头,如MouseDown、MouseUp。
Xaml代码:
<Window x:Class="冒泡路由.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:冒泡路由"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" MouseDown="SomethingClick">
<Grid MouseDown="SomethingClick">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label MouseDown="SomethingClick">
<StackPanel MouseDown="SomethingClick">
<TextBlock MouseDown="SomethingClick">Hello,World!!!</TextBlock>
<Label MouseDown="SomethingClick">World,Hello</Label>
<Image MouseDown="SomethingClick" Source="Images/1.jpg"></Image>
</StackPanel>
</Label>
<ListBox Name="listBox" Grid.Row="1"></ListBox>
</Grid>
</Window>
后台代码:
protected int eventCount = 0;
private void SomethingClick(object sender, MouseButtonEventArgs e)
{
eventCount++;
string message = "#" + eventCount.ToString() + ":
" +
" Sender: " + sender.ToString() + "
" +
" Source: " + e.Source + "
" +
" Original Source" + e.OriginalSource;
//将内容加入到listBox中。
listBox.Items.Add(message);
//如果将Handled属性设置为true,则终止传递。
//e.Handled = true;
}
效果:
当点击了图片,会从下到上地发生冒泡路由,直到冒泡到最外层的父级元素。
5.3)、隧道路由。
从上到下传递。 隧道路由比较容易识别,冒泡以Preview开头,如PreviewMouseDown、PreviewMouseUp。WPF通常成对地定义冒泡路由事件和隧道路由事件,这意味着如果发现冒泡的MouseUp事件,还可以找到PreviewUp隧道事件,隧道路由事件总是在冒泡路由事件之前被触发。如果隧道路由事件标记为已处理过,就不会发生冒泡路由事件,这是因为两个事件共享RoutedEventArgs类。
Xaml代码:
<Window x:Class="隧道路由事件.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:隧道路由事件"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" PreviewMouseDown="SuiDaoThings">
<Grid PreviewMouseDown="SuiDaoThings">
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" PreviewMouseDown="SuiDaoThings">
<Image Source="Images/1.jpg" PreviewMouseDown="SuiDaoThings"></Image>
</StackPanel>
<ListBox Name="listBox1" Grid.Row="1"></ListBox>
</Grid>
</Window>
后台代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
int count = 0;
private void SuiDaoThings(object sender, MouseButtonEventArgs e)
{
count++;
string message = "#" + count + ":
" +
" Sender: " + sender + "
" +
" Source " + e.Source + "
" +
" Original" + e.OriginalSource;
listBox1.Items.Add(message);
}
}
效果:
5.4)、处理挂起的事件。
有一种方法可接收被标记为处理过的事件,不过不是直接通过XAML关联事件处理程序,而是必须使用AddHandle()方法,AddHandle()方法提供了一个重载版本,该版本可以接收一个Boolean值作为他的第三个参数,如果将该参数设置了True,即使设置了Handle标志,也将接收事件。
Xaml代码,不直接指定事件处理函数:
<Window x:Class="冒泡路由.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:冒泡路由"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Name="window1">
<Grid Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="150"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label Name="label1">
<StackPanel Name="stackPanel1">
<Image Name="img1" Source="Images/1.jpg"></Image>
</StackPanel>
</Label>
<ListBox Name="listBox" Grid.Row="1"></ListBox>
</Grid>
</Window>
后台代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//通过AddHandle()方法添加事件处理程序。
img1.AddHandler(UIElement.MouseDownEvent,new MouseButtonEventHandler(SomethingClick),true);
stackPanel1.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(SomethingClick), true);
label1.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(SomethingClick), true);
grid1.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(SomethingClick), true);
window1.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(SomethingClick), true);
}
protected int eventCount = 0;
private void SomethingClick(object sender, MouseButtonEventArgs e)
{
eventCount++;
string message = "#" + eventCount.ToString() + ":
" +
" Sender: " + sender.ToString() + "
" +
" Source: " + e.Source + "
" +
" Original Source" + e.OriginalSource;
listBox.Items.Add(message);
//如果使用AddHandle()方法添加事件处理程序,那么设置Handled属性不会阻止路由,仍会继续向上冒泡路由传递。
e.Handled = true;
}
}
效果图,如果使用AddHandle()方法的重载设置为true的那个,设置e.Handled属性为True,会继续传递。
5.5)、附加事件。
Button元素有Click事件,而StackPanel元素则没有Click事件,如果要为StackPanel元素添加Click事件,则报错。这个时候附加事件的优势就体现出来了。
在Xmal中添加附加事件:
<Grid>
<!--由于StackPanel元素没有Click事件,所以XAMl解析器会将其解析成错误。-->
<StackPanel Margin="5" Click="DoSomeThing">
<Button Name="Cmd1">Cmd1</Button>
<Button Name="Cmd2">Cmd2</Button>
<Button Name="Cmd3">Cmd3</Button>
</StackPanel>
<!--添加附加事件。-->
<StackPanel Margin="5" Button.Click="DoSomeThing">
<Button Name="Cmd11">Cmd11</Button>
<Button Name="Cmd22">Cmd22</Button>
<Button Name="Cmd33">Cmd33</Button>
</StackPanel>
</Grid>
通过AddHandle()方法添加附加事件:
Xaml代码:
<StackPanel Margin="5" Name="stackPanel1"> <Button Name="Cmd1">Button1</Button> <Button Name="Cmd2">Button2</Button> <Button Name="Cmd3">Button3</Button> </StackPanel>
后台代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//通过AddHandler方法添加附加事件。
stackPanel1.AddHandler(Button.ClickEvent, new RoutedEventHandler(DoSomeThing));
}
private void DoSomeThing(object sender, RoutedEventArgs e)
{
}
}
6、WPF事件。
一般情况下,WPF最重要的事件包括这5类,分别是:生命周期事件、鼠标事件、键盘事件、手写笔事件和多点触控事件。
6.1)、生命周期事件。
生命周期事件是在元素被初始化,加载或卸载时发生这些事情。都是在FrameworkElement类中定义的。
所有元素的生命周期 |
|
Initialized |
当元素被初始化,并已根据Xaml标记设置了元素的属性之后发生,这时元素已经初始化,但窗口的其他部分可能尚未初始化,但是,此时还没应用样式和数据绑定,这时,IsInitialized属性为true。 |
Loaded |
当整个窗口已经初始化并应用了样式和数据绑定时,该事件发生,就是在元素呈现之前的最后一站,这时IsLoaded属性为true。 |
UnLoaded |
当元素被释放时,该事件发生。原因是包含元素的窗口被关闭或者特定的元素被从窗口中删除。 |
Window类的常用生命周期事件 |
|
名称 |
说明 |
ContentRendered |
在窗口首次呈现后立即发生,ContentRendered事件表明窗口已经完全可见,并且已经准备好接收输入 |
Activated |
当用户切换到该窗口时发生(从其他窗口切换到当前窗口),当窗口第一次加载也会引发该事件 |
Deactivated |
当用户从该窗口切换到其他窗口时发生。 |
Closing |
当关闭窗口时发生,不管是用户关闭窗口,还是通过代码WIndow.Close()。 |
Closed |
当窗口已经关闭后发生,但是让然可以访问元素对象,当然是在UnLoaded事件尚未发生之前 |
如果只对执行控件的第一次初始化感兴趣,完成这项任务的最好时机是触发Loaded事件。
6.2)、输入事件。
输入事件是当用户使用某些种类的外设硬件进行交互时发生的事件,如鼠标、键盘、手写笔或者多触控屏。输入事件可通过继承自InputEventArgs的自定义事件参数类型传递额外的信息。
6.2.1)、键盘输入。
当用户按下键盘上的一个键时,就会发生一系列事件。键盘处理永远不是那么的简单,一些控件可能会挂起这些事件中的某些事件,最明显的是TextBox控件,他挂起了TextInut事件,TextBox控键还挂起了KeyDown事件,通常可以使用隧道路由事件。
所有元素的按下键盘的顺序 |
||
名称 |
路由类型 |
说明 |
PreviewKeyDown |
隧道 |
当按下一个键时发生 |
KeyDown |
路由 |
当按下一个键时发生 |
PreviewTextInput |
隧道 |
当输入完成且元素正在接收文本输入时发生,对不会产生文本输入的按键(Ctrl键、shift键、方向键等),不会引发该事件 |
TextInput |
路由 |
当输入完成且元素正在接收文本输入时发生,对不会产生文本输入的按键,不会引发该事件 |
PreviewKeyUp |
隧道 |
当释放一个键时发生 |
KeyUp |
路由 |
当释放一个键时发生 |
Xaml中定义:
<Window x:Class="鼠标输入事件.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:鼠标输入事件"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="请输入要输入的内容:" FontSize="20" HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Margin="5" PreviewKeyDown="TextBox_PreviewKeyDown" KeyDown="TextBox_KeyDown" PreviewTextInput="TextBox_PreviewTextInput" TextInput="TextBox_TextInput" PreviewKeyUp="TextBox_PreviewKeyUp" KeyUp="TextBox_KeyUp" TextChanged="TextBox_TextChanged"></TextBox>
<ListBox Name="listBox1" Grid.Row="1" Grid.ColumnSpan="2" Margin="20"></ListBox>
</Grid>
</Window>
后台代码:
//PreviewKeDown事件处理程序。
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Key);
listBox1.Items.Add(message);
}
//KeyDown事件处理程序。
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Key);
listBox1.Items.Add(message);
}
//PreviewTextInput事件处理程序。
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Text);
listBox1.Items.Add(message);
}
//TextInput事件处理程序,不会执行此事件处理程序,因为TextBox元素挂起了TextInput事件。
private void TextBox_TextInput(object sender, TextCompositionEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Text);
listBox1.Items.Add(message);
}
//PreviewKeyUp事件处理程序。
private void TextBox_PreviewKeyUp(object sender, KeyEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Key);
listBox1.Items.Add(message);
}
//KeyUp事件处理程序。
private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
string message = string.Format("Event--->{0},Key--->{1}", e.RoutedEvent, e.Key);
listBox1.Items.Add(message);
}
//TextChanged事件处理程序。
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string message = string.Format("Event--->{0}", e.RoutedEvent);
listBox1.Items.Add(message);
}
效果图,在文本框中输入了一个K键:
6.2.2)、 焦点。
在Windows的世界中,用户每次只能使用一个控件,当前接收用户按键的控件是具有焦点的控件。为了让控件能接受焦点,必须将Focusable设置为true,这是所有控件的默认值,如果为TextBox元素的Focusable元素设置为false,就不会获取焦点了,可以通过TabIndex属性设置按下tab键后的顺序。
6.2.3)、获取键盘状态。
当发生按键事件时,经常需要知道更多的信息,不仅需要知道按下的是哪个键,其他键是否按下了也同样重要,特别是Shift键、Ctrl键、Alt键。
KeyBoardDevice属性提供了KeyBoardDevice类的一个实例,它的属性包含了当前是哪个元素具有焦点以及按下了哪些修饰键,可用代码显示。
Xmal代码:
<TextBox PreviewKeyDown="TextBox_PreviewKeyDown"></TextBox>
后台代码:
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
MessageBox.Show("你点击了Control键");
}
//还可以使用KeyBoard类,该类和KeyboardDevice类非常类似,只是Keyboard类由静态成员构成。
if (Keyboard.IsKeyDown(Key.LeftCtrl))
{
MessageBox.Show("按下了Ctrl键盘");
}
}
6.2.4)、鼠标输入。
鼠标事件执行几个关联的任务,当鼠标移到某个元素上时,可通过最基本的鼠标事件进行响应,这些都是MouseEnter和MouseLeave(直接事件)。
所有元素的鼠标单击事件(按顺序排序) |
||
名称 |
路由类型 |
说明 |
PreviewMouseLeftButtonDown PreviewMouseRightButtonDown |
隧道 |
按下鼠标左键时发生 |
MouseLeftButtonDown MouseRightButtonDown |
隧道 |
按下鼠标左键时发生 |
PreviewMouseLeftButtonUp PreviewMouseRightButtonUp |
隧道 |
按下鼠标右键时发生 |
MouseLeftButtonUp MouseRightButtonUp |
隧道 |
按下鼠标右键时发生 |
PreviewMouseWheel |
隧道 |
鼠标滚轮动作 |
MouseWheel |
冒泡 |
鼠标滚轮动作 |
6.2.5)、捕获鼠标。
当鼠标被一个元素捕获时,就不能与其他元素进行交互了(不能单击窗口中的其他元素),鼠标捕获通常用于短时间的操作。
Xaml代码:
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Canvas Background="AliceBlue"></Canvas>
<Button Name="btn1" Grid.Row="1" Margin="20" Click="Button_Click">Hello,World!!!</Button>
</Grid>
后台代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
Mouse.Capture(btn1);
}
当点击button按钮后,整个窗口的其他元素和按钮就不能点击了,只有把光标移开该窗口,然后点击一下,这个窗口的元素才可以点击。
6.2.6)、鼠标拖放。
拖放操作的方法和事件都集中在System.Windows.DragDrop类中。
拖放操作有以下3个步骤:
1)、用户单击元素,并保持鼠标按键为按下状态,这时,某些信息被搁置起来,并且拖放操作开始。
2)、用户将鼠标移动到其他元素上,如果该元素可接受正在拖动的内容的类型,鼠标指针会变成拖放图标,否则鼠标指针会变成内部有一条线的圆形。
3)、当用户释放鼠标键时,元素接收信息并决定如何处理接收到的信息,在没有释放鼠标键时,可按下Esc键取消该操作。
Xaml代码:
<Window x:Class="鼠标拖放.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:鼠标拖放"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--为源元素设置MouseDown事件-->
<Label Name="lbl1" MouseDown="lbl1_MouseDown" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">Hello,World!!!</Label>
<TextBox Name="textBox1" Grid.Column="1" Height="35" Margin="10"></TextBox>
<!--为目标属性设置AllowDrop属性,然后再Drop事件中写内容-->
<Label Name="lbl2" Grid.Row="1" Drop="lbl2_Drop" AllowDrop="True" HorizontalAlignment="Center" VerticalAlignment="Center">今天天气好晴朗!!!</Label>
</Grid>
</Window>
后台代码:
/// <summary>
/// 源元素的MouseDown事件。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl1_MouseDown(object sender, MouseButtonEventArgs e)
{
//转换成Label对象。
Label lbl = (Label)sender;
//DragDrop类用于拖动操作。
//DoDragDrop()方法用于启动拖放操作。 源对象,源对象的属性,拖放的效果(复制,移动...)
//DoDragDrop()方法重载参数:源对象,源对象的属性,拖放的效果(复制,移动...)
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Scroll);
}
/// <summary>
/// 目标元素的Drop事件。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl2_Drop(object sender, DragEventArgs e)
{
//获取指定数据对象,格式由字符串指定。
((Label)sender).Content = e.Data.GetData(DataFormats.Text);
}
6.2.7)、多点触控输入(适用于带触摸屏的电脑)。
所有元素的原始触控事件 |
||
名称 |
路由类型 |
说明 |
PreviewTouchDown |
隧道 |
用户触摸元素时发生 |
TouchDown |
冒泡 |
用户触摸元素时发生 |
PreviewTouchMove |
隧道 |
用户移动到触摸屏上的手指时发生 |
TouchMove |
冒泡 |
用户移动到触摸屏上的手指时发生 |
PreviewTouchUp |
隧道 |
用户移开手指,结束触摸时发生 |
TouchUp |
冒泡 |
用户移开手指,结束触摸时发生 |
TouchEnter |
无 |
触点从元素外进入元素内时发生 |
TouchLeave |
无 |
触点离开元素时发生 |
End。
以上是关于路由事件的主要内容,如果未能解决你的问题,请参考以下文章
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段