后台代码文件中的事件处理器
在前面部分,你学习了怎么去将特性和相应属性联系到一起。然而,为了使控件工作你可能有时需要给特性添加时间处理器。在前面的XAML文件中,你必须添加一个OnTextChanged事件处理器到TextBox.的TextChanged属性上。你也必须使用两个click事件处理器定义两个按钮的Click属性:btnChangeColor_Click 和 btnChangeSize_Click。
假定这在后台代码文件中是叫做OnTextChanged,btnChangeColor_Click和 btnChangeSize_Click的方法。下面是这个例子的相应的后台代码文件:
using System;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;
namespaceWPFOverview
{
public partial class FirstWPFProgram :Window
{
public FirstWPFProgram ()
{
InitializeComponent();
}
private void OnTextChanged(objectsender,
TextChangedEventArgs e)
{
textBlock.Text = textBox.Text;
}
private void btnChangeColor_Click(objectsender,
RoutedEventArgs e)
{
if (textBlock.Foreground ==Brushes.Black)
textBlock.Foreground =Brushes.Red;
else
textBlock.Foreground =Brushes.Black;
}
private void btnChangeSize_Click(objectsender,
RoutedEventArgs e)
{
if (textBlock.FontSize == 11)
textBlock.FontSize = 24;
else
textBlock.FontSize = 11;
}
}
}
注意事件处理器必须有正确的签名。WPF里的事件模型和先前版本的.NET有轻微的差别。WPF支持一个新的基于事件路由的模型。前面代码的其他部分和你熟悉的Windows Forms应用程序中使用的类似。
运行这个例子将生成图1-1里显示的结果。如果你在文本框里输入任何文字,
text block将显示相同的文字。另外,颜色和字体大小将由哪个按钮被点击决定。
只含代码的例子
前面提到,XAML在 创建WPF程序的时候不是必须的。WPF完全支持只含代码的实现,尽管这个用法很不常见。只含代码的实现有利有弊。只含代码的方法的一个好处就是它让你可以完全控制定制。举个例子,当你想根据用户的输入条件性地添加或者替换控件时,你可以在代码里轻易地实现条件逻辑。这在XAM里是很困难的,因为XAML里的控件被作为固定不变的资源地嵌入到你的程序集里。一个坏处就是既然WPF控件不包括含参数的构造器,在WPF中开发一个只含代码的应用程序是很枯燥的。即使是添加一个简单的控件,比如一个按钮,到你的应用程序中需要多行代码。
在下面的例子中,我们将前面的例子,FirstWPFProgram,转换成一个只含代码的应用程序。打开WPFOverview项目,添加一个WPF Window,命名为CodeOnly。打开CodeOnly.xaml文件,从Window中移除Grid控件。文件应该看起来像下面:
<Windowx:Class="WPFOverview.CodeOnly"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Window>
打开后台代码文件,CodeOnly.xaml.cs,添加下面的代码到文件中:
using System;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;
namespaceWPFOverview
{
public partial class CodeOnly : Window
{
private TextBlock textBlock;
private TextBox textBox;
public CodeOnly()
{
InitializeComponent();
Initialization();
}
private void Initialization()
{
// Configure the window:
this.Height = 300;
this.Width = 300;
this.Title = "Code OnlyExample";
// Create Grid and StackPanel andadd them to window:
Grid grid = new Grid();
StackPanel stackPanel = newStackPanel();
grid.Children.Add(stackPanel);
this.AddChild(grid);
// Add a text block to stackPanel:
textBlock = new TextBlock();
textBlock.Margin = new Thickness(5);
textBlock.Height = 30;
textBlock.TextAlignment =TextAlignment.Center;
textBlock.Text = "HelloWPF!";
stackPanel.Children.Add(textBlock);
// Add a text box to stackPanel:
textBox = new TextBox();
textBox.Margin = new Thickness(5);
textBox.Width = 200;
textBox.TextAlignment =TextAlignment.Center;
textBox.TextChanged += OnTextChanged;
stackPanel.Children.Add(textBox);
// Add button to stackPanel used tochange text color:
Button btnColor = new Button();
btnColor.Margin = new Thickness(5);
btnColor.Width = 200;
btnColor.Content = "Change TextColor";
btnColor.Click +=btnChangeColor_Click;
stackPanel.Children.Add(btnColor);
// Add button to stackPanel used tochange text font size:
Button btnSize = new Button();
btnSize.Margin = new Thickness(5);
btnSize.Width = 200;
btnSize.Content = "Change TextColor";
btnSize.Click += btnChangeSize_Click;
stackPanel.Children.Add(btnSize);
}
private void OnTextChanged(object sender,
TextChangedEventArgs e)
{
textBlock.Text = textBox.Text;
}
private voidbtnChangeColor_Click(object sender,
RoutedEventArgs e)
{
if (textBlock.Foreground ==Brushes.Black)
textBlock.Foreground =Brushes.Red;
else
textBlock.Foreground =Brushes.Black;
}
private void btnChangeSize_Click(objectsender,
RoutedEventArgs e)
{
if (textBlock.FontSize == 11)
textBlock.FontSize = 24;
else
textBlock.FontSize = 11;
}
}
}
这个代码列表将产生和图1-1中显示的相同结果。
你可以看到CodeOnly类和传统的Windows Forms类应用程序中的form类很相似。它从Window基类继承并为TextBlock和TextBox添加了私有成员变量。注意控件怎么被添加到他们的父母和事件处理器是怎么添加的。
只含XAML的例子
在前面的部分中,你学习了怎么使用XAML加代码和只含代码的技术创建相同的WPF应用程序。标准的开发WPF程序的方法是同时使用XAML和后台代码文件。也就是说,你使用XAML去布局你的UI,使用代码区实现时间处理器。对于动态UI的应用程序,你可能想使用只含代码的方法。
但是,对于简单的应用程序,也可以使用只含XAML文件而不写任何C#代码的方法。乍一看,一个松散的XAML文件看似毫无用处——毕竟,没有代码的UI怎么去驱动它呢?然而,XAML提供了一些特性允许你不使用后台代码文件展示特定的功能。例如,你可以开发只含XAML文件的包含动画,事件触发器和数据绑定的应用程序。
这里我们模仿FirstWPFProgram例子创建一个松散的XAML应用程序。尽管它不能完美地产生如图1-1显示的结果,这个只含XAML的应用程序仍然产生了一个比HTML世界更令人印象深刻的结果。
添加一个WPF Window到WPFOverview项目中,命名为XAMLOnly。下面是这个例子的标记语句:
<Windowx:Class="WPFOverview.XAMLOnly"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"Height="300" Width="300">
<Grid>
<StackPanel>
<TextBlock Name="textBlock"Margin="5"
TextAlignment="Center" Height="30"
Text="{BindingElementName=textBox,Path=Text}"/>
<TextBoxName="textBox" Margin="5" Width="200"
TextAlignment="Center"Text="Hello, WPF!"/>
<Button Margin="5"Width="200"
Content="Change TextColor">
<Button.Triggers>
<EventTriggerRoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="textBlock"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
From="Black" To="Red"Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Margin="5"Width="200"
Content="Change TextSize">
<Button.Triggers>
<EventTriggerRoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="textBlock"
Storyboard.TargetProperty="FontSize"
From="11" To="24" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</StackPanel>
</Grid>
</Window>
这个XAML文件首先将 TextBlock的 Text属性绑定到 TextBox的 Text属性上。这个数据绑定允许你通过在 TextBox里输入文字来改变 TextBlock的文字。接着创建了两个按钮,它们的功能是改变文字颜色和字体。这个可以通过按钮的事件触发器来做到,它开启了一个color animation和一个double animation,由按钮被点击决定。
尽管这个应用程序缺少后台代码文件,这些按钮仍能工作。当然,这个只含XAML的例子不能完全复制前面只含后台代码文件的例子。原因是尽管XAML文件里的事件触发器能开启一个动画,它们不能包含if语句,for循环和其他任何计算算法。