界面和交互的设计决定了应用程序在移动设备上的用户体验,控件是界面的重要组成部分,也是和用户交互的主要接口。本文将详细介绍Windows Phone 7常用的布局和控件,以及控件外观自定义的方法。

正如任何一个C#程序都会以Main()方法为程序入口点一样,本文的入口点从创建一个新的Windows Phone Application开始。本文的内容正确实践之前,要确保已经安装Microsoft Visual Studio 2010 Express for Windows Phone Beta。
Windows Phone应用程序页面
创建完Windows Phone Application以后,在解决方案资源管理器里可以看到Visual Studio根据模板生成的项目文件,App.xaml和MainPage.xaml是本文的重点关注对象,App.xaml用来定义应用程序的主入口点,初始化应用程序作用域内的资源和显示应用程序的用户界面。MainPage.xaml用来定义带有用户界面的应用程序页面。App.xaml.cs和MainPage.xaml.cs是交互逻辑的代码文件,Silverlight和WPF都是采用界面和逻辑分开的方式,使设计人员专注于设计,开发人员专注于开发 ,Silverlight for Windows Phone也是如此。Windows Phone应用程序页面都继承于PhoneApplicationPage, PhoneApplicationPage是MainPage.xaml的根节点,包含了当前页面内所有的布局和控件。
以下方法可以实现跳转到另一页面:
this.NavigationService.Navigate(new Uri("目标XMAL文件", UriKind.Relative));
Goback(),GoForward()方法可以实现在不同的页面间轻松游走。
在页面的构造函数下加入以下代码定义屏幕方向:
SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
在MainPage.xaml文件中如下位置添加屏幕旋转事件
<phone:PhoneApplicationPage
...
OrientationChanged="PhoneApplicationPage_OrientationChanged">
...
</phone:PhoneApplicationPage>
在private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)里可以进行相应的事件处理。
屏幕旋转后,控件可能需要重新布局,在下文中将介绍Windows Phone7应用程序常见的几种布局。
Windows Phone应用程序容器控件
MainPage.xaml的部分代码如下:
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
       <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
 
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12">
        <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="page name" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
   </StackPanel>
 
   <Grid x:Name="ContentGrid" Grid.Row="1">
    </Grid>
</Grid>
1.       Grid控件
在示例中Grid 控件包含了StackPanel控件,用于布局的容器控件是可以包含其他的容器控件的。Grid定义由列和行组成的网格布局。Grid.RowDefinitions和Grid.ColumnDefinitions集合分别包含RowDefinition和ColumnDefinition用来定义行和列的宽度和高度,行列的数量是根据集合中子对象的数量被定义的。各子对象中Grid.Row和Grid.Column属性用于定义在网格中的位置。示例中定义了两行,因为只有一列,所以Grid.ColumnDefinitions没有被定义。TitlePanel在第一行,Grid.Row="0",ContentGrid在第二行,Grid.Row="1"。
2.       StackPanel控件
StackPanel控件可以使布局内的各子对象以水平或垂直的方式顺序排列。通过设置Orientation="Vertical"或者Orientation="Horizontal"来定义排列方式。默认情况以垂直方向排列子对象。
除了示例中Grid 控件和StackPanel控件之外,还有其他的容器控件。
3.       Canvas
    以绝对位置的方式布局。通过设置子对象Canvas.Left 指定对象与所在的 Canvas 的左侧之间的距离(x 坐标);Canvas.Top 指定对象与所在的 Canvas 的顶部之间的距离(y 坐标)。
4.       ScrollViewer
    ScrollViewer控件用来表示可包含其他可见元素的可滚动区域。设置HorizontalScrollBarVisibility 和VerticalScrollBarVisibility属性可以控制水平滚动条和垂直滚动条的状态。
5.       Border
    Border控件不太适用于布局,但是确实是容器控件。Border控件可以为其包含的子对象绘制边框或背景。下文中使用Microsoft Expression Blend for Windows Phone自定义按钮控件就会用到Border控件。
Windows Phone应用程序常用控件
1.       文本控件
 
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
 
示例中的TextBlock控件用于显示少量文本,Text 属性对应文本内容。Text 属性可以在XAML文件里动态定义,也可以在C#代码中随时修改。利用x:Name属性定义的名称来确定要修改的TextBlock控件。在这个示例里,可以通过给ApplicationTitle.Text设置新的字符串来改变文本内容。
TextBlock控件无法接收用户输入的文本,也不太适合过长文本的显示。TextBox控件可以胜任此类任务,代码如下:
 
<TextBox Height="72" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBox1" Text="TextBox" VerticalAlignment="Top" Width="460" />
 
MaxLength属性可以控制文本的字符串长度。
对于密码输入,还可以使用PasswordBox控件,代码如下:
 
<PasswordBox Height="72" HorizontalAlignment="Left" Margin="10,92,0,0" Name="passwordBox1" VerticalAlignment="Top" Width="460" />
 
PasswordBox 控件还可以使用PasswordChar定义密码显示的字符。

 
2.       按钮控件
按钮控件包含Button控件和HyperlinkButton控件,HyperlinkButton控件想相比Button控件可以不必处理单击事件就可以自动导航到为 NavigateUri 指定的Uri。
 
<Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="10,174,0,0" Name="button1" VerticalAlignment="Top" Width="160" />
<HyperlinkButton Content="HyperlinkButton" Height="30" HorizontalAlignment="Left" Margin="176,195,0,0" Name="hyperlinkButton1" VerticalAlignment="Top" Width="200" />
 
Button控件和HyperlinkButton控件都可以使用Content属性来设置按钮上的文字,除此之外,HyperlinkButton控件支持NavigateUri属性来定义目标Uri。
 
3.       选择控件
RadioButton用于一组选项中选择一个选项,RadioButton有两种把多个RadioButton控件分成一组。放置到同一个父控件内,或者设置GroupName属性。使用GroupName属性也可以把同一个父控件内的RadioButton分为多组。同一组中的RadioButton会相互排斥,也就是说用户只能使一个按钮的状态为选中状态。
 
<RadioButton Content="RadioButton" Height="72" HorizontalAlignment="Left" Margin="10,10,0,0" Name="radioButton1" VerticalAlignment="Top" />
 
RadioButton可以设置为选中,未被选中,禁用状态。默认为未被选中状态,设置IsChecked="True"可把状态变更为选中,设置IsEnabled="False"可以把状态变更为禁用。
CheckBox用于选择多个选项。同RadioButton一样,可以通过设置IsChecked和IsEnabled来控制状态。
 
<CheckBox Content="CheckBox" Height="72" HorizontalAlignment="Left" Margin="10,166,0,0" Name="checkBox1" VerticalAlignment="Top" />
 
CheckBox设置IsThreeState="True"后可以增加一种状态不确定状态。
Slider适合在一个范围内选择一个值。
 
<Slider Height="84" HorizontalAlignment="Left" Margin="0,326,0,0" Name="slider1" VerticalAlignment="Top" Width="460" />
Maximum和Minimum属性用来定义最大值和最小值。Value属性是Maximum和Minimum之间的一个值,用来定义Slider当前的值。默认的情况下,Minimum="0" Maximum="10"。用户可以通过拖动来改变Slider的值,SmallChange属性可以定义拖动的精度,也可以通过点击来改变Slider的值,LargeChange属性来定义值改变的精度。根据界面布局的需要,利用Orientation属性可以设置水平和垂直方向。
 
自定义按钮控件外观
如果你发现Windows Phone 7的平凡的控件外观与你的应用程序界面格格不入,可以使用Microsoft Expression Blend for Windows Phone Beta重新设计控件的外观。在Visual Studio的解决方案资源管理器中找到MainPage.xaml,鼠标右键点击在菜单里选择Open in Expression Blend。自定义控件外观要先创建一个控件模板。在Objects and Timeline面板中找到button1,右键点击,在弹出菜单中选择Edit Template | select Create Empty,为模板命名为ButtonControlTemplate。可以看到Objects and Timeline下的Template下有一个Grid布局控件,对于按钮来说Border控件更适合用来绘制边框和背景。右键点击Grid,在弹出菜单中选择Change Layout Type|Border。
空白的Border不能显示任何内容,在Properties面板下的Appearance面板上设置Border的边框宽度为2像素,圆角10像素。

   
在Brushes面板上设置背景颜色,选择Gradient brush来实现渐变效果。分别设置两端为白色和紫色。
接下来设置BorderBrush,使用Solid color brush实现一个灰色的边框。
到此,按钮的外观已经设计完成了,但是按钮还没有文字。保证Border在Objects and Timeline面板是选中状态因为需要从Assets面板中添加一个TextBlock控件到Border。
设置一下TextBlock在Border的布局。
设置HorizontalAlignment和VerticalAlignment为Center让TextBlock在Border里居中。接下来需要把TextBlock的Text属性绑定到Button的Content属性。这样,改变Text属性,Button的Content属性也会一同更改,在Common Properties目录下找到Advanced property options,弹出菜单中选择Template Binding|Content即可完成绑定。
目前这个按钮在点击或者获得焦点的时候还不会有任何变化。下面将以点击时为例,制作一个响应点击的动画效果。
确认Objects and Timeline上已经选择了Border控件。切换到States面板,在CommonStates下点击Pressed,会自动开始录制。在时间线1秒的位置处,更改一次Border的背景,在2秒的位置处复原到初始状态。在点击按钮时触发的动态效果就制作完成了。

总结:在Windows Phone 7中,选用合适的布局和控件有助于设计和开发出更优秀的用户界面。利用xaml和cs文件可以是界面和逻辑的分离,控件开发中要着重于xaml的描述,配合Expression Blend,还可以创造出更华丽生动的用户体验。