现在大多数的 UI 框架都是事件驱动的,WPF 也是。所有的控件,包括窗体(Window控件)都提供了大量的事件可以订阅。您订阅这些事件,这表明您的应用程序将在事件发生的时候接受程序到通知并且您可以对这些事件形成响应。
有很多不同类型的事件,大量的事件用于在用户使用鼠标键盘和你的应用互动的时候。在大多数的控件上你会找到 KeyDown, KeyUp, MouseDown, MouseEnter, MouseLeave, MouseUp 等类的事件。
我们来看看事件怎么工作的吧。这有点复杂,但现在我们只要知道怎么在XAML和代码中通过事件连接起来就可以了,看个例子:
<Window x:Class="WpfTutorialSamples.XAML.EventsSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EventsSample" Height="300" Width="300">
<Grid Name="pnlMainGrid" MouseUp="pnlMainGrid_MouseUp" Background="LightBlue">
</Grid>
</Window>
注意我们在Grid中订阅了MouseUp事件,菜单了方法名pnlMainGrid_MouseUp。这个方法会在代码中定义成这样:
private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("You clicked me at " + e.GetPosition(this).ToString());
}
MouseUp 事件的使用不是一个名称为MouseButtonEventHandler的委托,它有两个参数,sender(发生事件的控件),MouseButtonEventArgs(一些细节的信息,我们上面的例子中通过它获取了鼠标的位置)。
某些事件会使用同一个委托,MouseUp 和MouseDown 例如使用MouseButtonEventHandler,注意MouseMove 使用的是MouseEventHandler。当你定义事件处理方法的时候,你需要知道事件使用的委托,文档里可以找到。
幸运的是, Visual Studio 可以帮助我们生成正确的事件处理方法. 最简单的办法是, 在XAML中输入事件的名字, VS的IntelliSense就会提供生成新事件处理方法的选项:
当你选中<New Event Handler>Visual Studio 会在代码文件中生成合适的事件处理方法, 名字会长这样: <control name>_<event name>, 这个例子中就是 pnlMainGrid_MouseDown. 右键事件的名字并在弹出的菜单中选中Navigate to Event Handler你就会看到新生成的方法了.
上面的就是最常见的事件订阅方法, 但有的时候你想直接在代码中订阅事件. 在C#中这会使用到+=语法, 你可以将一个事件处理方法直接添加到对象中. 详细的解释需要一个单独的C#例子, 作为比较, 这是一个例子:
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfTutorialSamples.XAML
{
public partial class EventsSample : Window
{
public EventsSample()
{
InitializeComponent();
pnlMainGrid.MouseUp += new MouseButtonEventHandler(pnlMainGrid_MouseUp);
}
private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("You clicked me at " + e.GetPosition(this).ToString());
}
}
}
一样的,你需要知道使用哪个委托, 还是一样的, Visual Studio 会帮你, 当你输入完:
pnlMainGrid.MouseDown +=
Visual Studio 会显示:
按下 [Tab] 键两次 Visual Studio 就会生成正确的事件处理方法, 就在当前方法的下面. 你需要实现方法的内容. 当你使用以上方法订阅事件的时候, 就不需要再通过XAML订阅了.