三、事件处理程序与代码隐藏
例如,为一个Page添加一个Button控件,并为该Button添加事件名称Button_Click:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="ExampleNamespace.ExamplePage"> <Button Click="Button_Click" >Click Me!</Button> </Page>
namespace ExampleNamespace { public partial class ExamplePage { void Button_Click(object sender, RoutedEventArgs e) { Button b = e.Source as Button; b.Foreground = Brushes.Red; } } }
于是,这样就把Button连接到事件处理程序Button_Click。
四、命名元素
例如,在XAML文件中,为Grid命名为grid1:
<Grid x:Name="grid1"> </Grid>
或者,在VS的设计窗口中,设置Grid元素属性,将名称属性改为grid1。
现在,可以在C#代码中使用grid1了:
MessageBox.Show(String.Format("The grid is {0}x{1} units in size.", grid1.ActualWidth, grid1.ActualHeight));
注意,与WinForm不同,WPF的控件不必每个都为之命名。
五、附加属性与附加事件——一个WPF例子
借用书中EightBalls的例子,其中UI如下:
在上面的TextBox输入问题,然后点击按钮,程序在下面的TextBox输出答案。
<Window x:Class="EightBall.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Eight Ball Answer" Height="328" Width="412" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.Background> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.00" Color="Red" /> <GradientStop Offset="0.50" Color="Indigo" /> <GradientStop Offset="1.00" Color="Violet" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Grid.Background> <TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10,10,13,10" Name="txtQuestion" TextWrapping="Wrap" FontFamily="Verdana" FontSize="24" Grid.Row="0" > [Place question here.] </TextBox> <Button VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,0,0,20" Width="127" Height="23" Name="cmdAnswer" Click="cmdAnswer_Click" Grid.Row="1"> Ask the Eight Ball </Button> <TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10,10,13,10" Name="txtAnswer" TextWrapping="Wrap" IsReadOnly="True" FontFamily="Verdana" FontSize="24" Foreground="Green" Grid.Row="2"> [Answer will appear here.] </TextBox> </Grid> </Window>
C#实现代码:
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Input; namespace EightBall { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void cmdAnswer_Click(object sender, RoutedEventArgs e) { // Dramatic delay... this.Cursor = Cursors.Wait; System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1)); AnswerGenerator generator = new AnswerGenerator(); txtAnswer.Text = generator.GetRandomAnswer(txtQuestion.Text); this.Cursor = null; } } }
1.XAML指定一个语言功能,该功能的属性版本称为附加属性,事件版本称为附加事件。 从概念上讲,可以将附加属性和附加事件视为可以在任何 XAML 元素/对象实例上设置的全局成员。 但是,元素/类或更大的基础结构必须支持附加值的后备属性存储。在特性语法中,您可以采用“所有者类型.属性名”的形式指定附加属性。
2.在Grid.Property嵌套LinerGridientBrush,再嵌套LinearGradientBrush.GradientStops,并对此设置属性。
3.标记扩展:x:Type,x:Static,x:Array,x:Null。语法:{MarkupExtensionClass Argument}。
标记扩展继承自基类System.Windows.Markup.MarkupExtention。例如,
<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush}" >
这等同于将标记扩展嵌套到对象属性:
<Button ... > <Button.Foreground> <x:Static Member="SystemColors.ActiveCaptionBrush"></x:Static> </Button.Foreground> </Button>
4.附加属性:通常用于容器中的控件。每个控件都有其固有的附加属性,取决于它所在的容器。例如:
<TextBox Grid.Row=”0”> </TextBox> <Button Grid.Row=”1”> Ask the Eight Ball </Button> <TextBox Grid.Row=”2”> </TextBox>
附加属性不是真正的属性,它们被转换成方法调用:DefiningType.SetPropertyName()。如上代码,会被转换成:
Grid.SetRow().
Grid.SetRow(txtQuestion, 0);
5.嵌套元素:Window包含Grid,Grid包含TextBox和Button。
IList.Add();
IDictionary.Add();
ContentProperty:
例如,
<LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.00" Color="Red" /> <GradientStop Offset="0.50" Color="Indigo" /> <GradientStop Offset="1.00" Color="Violet" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush>
GradientStops属性返回一个GradientStopCollection对象,而GradientStopCollection实现IList接口。因此,每个GradientStop调用IList.Add()方法。
上述XAML代码等同于:
GradientStop gradientStop1 = new GradientStop(); gradientStop1.Offset = 0; gradientStop1.Color = Colors.Red; IList list = brush.GradientStops; list.Add(gradientStop1);
6.Collection。某些属性可能支持不止一种Collection。因此,要添加标签指定Collection类:
<LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStopCollection> <GradientStop Offset="0.00" Color="Red" /> <GradientStop Offset="0.50" Color="Indigo" /> <GradientStop Offset="1.00" Color="Violet" /> </GradientStopCollection> </LinearGradientBrush.GradientStops> </LinearGradientBrush>