原文:Windows Phone开发(16):样式和控件模板

在前面资源一文中也提过样式,样式就如同我们做HTML页排版时常用到的CSS样式表,它是对于特定娄型的可视化元素,应该可以直接说是针对控件的一种可重用的属性设置列表,这样对于需要设置相同属性值的同类型的多个控件来讲是大大提高效率,我们不必要为每个控件做重复的动作。

下面是一个TextBox的样式示例,我们希望通过引用资源中的样式,使得页面上的所有TextBox控件都具有统一的外观,而且都只能输入数字。

    <phone:PhoneApplicationPage.Resources>
<!--不带key的样式,应用于所有TextBlock元素-->
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="40"/>
<Setter Property="Foreground" Value="Yellow"/>
</Style>
<!--带key的样式,只有引用该资源的元素才应用-->
<Style x:Key="MyTextBoxStyle" TargetType="TextBox">
<Setter Property="FontSize" Value="40"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="InputScope">
<Setter.Value>
<InputScope>
<InputScopeName NameValue="Number"/>
</InputScope>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> <TextBlock Grid.Row="0" x:Name="PageTitle" Text="样式示例" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,10,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="文本一:"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="文本二:"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="文本三:"/>
<TextBlock Grid.Column="0" Grid.Row="3" Text="文本四:"/>
<TextBlock Grid.Column="0" Grid.Row="4" Text="文本五:"/> <TextBox Grid.Column="1" Grid.Row="0" Style="{StaticResource MyTextBoxStyle}" />
<TextBox Grid.Column="1" Grid.Row="1" Style="{StaticResource MyTextBoxStyle}" />
<TextBox Grid.Column="1" Grid.Row="2" Style="{StaticResource MyTextBoxStyle}" />
<TextBox Grid.Column="1" Grid.Row="3"/>
<TextBox Grid.Column="1" Grid.Row="4"/>
</Grid>
</Grid>
样式在资源中有两种声明方式,一种是带键值,一种是不带键值的。

1、带key的样式,不会自动应用到元素/控件上,除非元素的Style属性引用了该资源的键;

2、不带键的样式资源,将自动应用于当前页面(如果资源声明在当前页)中的所有同类型的元素。
所以,在上例中,你会看到左边的一列TextBlock,它们都没有显式设置Style属性,但它们都一致引用了第一个样式,因为该样式是不带键的。

而右面的一列TextBox,由于后面两个没有显式设置Style属性,故它们保持默认样式。

控件模板并不常用,除非你对控件的外观的行为特效有较高的要求,因为我们不能把控的外观弄得太花了,这样反而降低用户体验,简洁明了的东西其实是让人看的最舒服的。

要自定义控件模板,首先要了解一下状态。

如果你以前做过WPF开发你会知道,在.NET 3.5的时候,自定义控件模板,针对控件状态的改变所做出的应对策略是通过触发器来完成的,但到了.NET 4,就有了状态的概念,而Silverlight 3也引入这概念,这样使得控件的状态管理更方便也更灵活了。

还有一点就是状态有分组的,每个组里面的状态是互斥的,也就是不能同时发生,每个时刻只允许组内一个状态发生,但不同组之间的状态是不冲突的。
了解了状态后,还有一概念,就是部件,这个好理解了,比如我们要组装一辆汽车,需要哪些部件,轮胎放哪个位置,车门怎么放置等。对于复杂的控件,有可以有N个控件或UI元素组成,由于WPF是把UI和代码逻辑完全分开的,但有些时候我们也希望与UI元素进行交互,如某UI元素是否透明,是否被移动了,或者模板中的按钮可能要触发其单击事件等,为了方便后台代码能够找到这些部件,所以在控件开发的时候会为这些特定部件统一命名。
那么,怎么知道一个控件的模板中有哪些状态,有哪些特定的部件呢?从控件类的定义所附加的Attribute特性来获取,如,Button控件的状态和部个有:
    // 摘要:
// 表示按钮控件。
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
[TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
public class Button : ButtonBase
Button控件是内容控件,它并不复杂,所以没有部件。
下面,我们就以Button为例为它自定义一个模板,注意,定义模板写XAML比较花时间,你可以选择使用设计工具Express Blend来完成,当然了,在学习的时候,最好还是动手写一下。
    <phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="Template1" TargetType="ButtonBase">
<Grid>
<!--状态组-->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="pressed"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:0.5"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="disable"
Storyboard.TargetProperty="Opacity"
To="0.5" Duration="0:0:0.5"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="focussbd"
Storyboard.TargetProperty="Opacity"
To="0.88"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="background" Background="{TemplateBinding Background}">
<Rectangle x:Name="pressed" Opacity="0" RadiusX="2" RadiusY="2">
<Rectangle.Fill>
<LinearGradientBrush
StartPoint=".5,0"
EndPoint=".5,1">
<GradientStop Color="SkyBlue" Offset=".1"/>
<GradientStop Color="Blue" Offset=".9"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter x:Name="ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
<Rectangle x:Name="disable" Opacity="0" Fill="Gray" RadiusX="2" RadiusY="2"/>
<Border x:Name="focussbd" BorderBrush="LightGreen" BorderThickness="2" CornerRadius="2" Opacity="0"/> </Grid>
</Border>
</Grid>
</ControlTemplate>
</phone:PhoneApplicationPage.Resources> <Grid x:Name="ContentPanel" Margin="12,0,12,0">
<Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="135,155,0,0" Name="button1" VerticalAlignment="Top" Width="160" Template="{StaticResource Template1}" />
</Grid>

控件模板有时候很难一两句话讲清楚,别看它好像很多东西,其实很简单,它无非包括两个东西——状态和UI元素,至于怎么个布局法,完全取决于你希望怎么设计了。

如果你说有什么办法可以帮助学习和研究控件模板,当然有的,前面说了,就是Express Blend这是一个很好用的设计工具,你把它当作图形处理软件也可以,它会根你的设计自动生成XAML,很好用。
Windows Phone SDK带的这个工具是免费的,你在开发的过程中千万不要小气哦,大胆地去用吧,不用钱又这么强大的东东,你不能浪费。

Windows Phone开发(16):样式和控件模板的更多相关文章

  1. 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理

    [源码下载] 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) ...

  2. WPF笔记(1.9 样式和控件模板)——Hello,WPF!

    原文:WPF笔记(1.9 样式和控件模板)--Hello,WPF! 资源的另一个用途是样式设置: <Window >  <Window.Resources>    <St ...

  3. WPF 10天修炼 第七天- WPF资源、样式、控件模板

    WPF资源 对象资源 WPF允许在XAML标记的任意位置定义资源.比如在特定的控件.窗口或应用程序级别定义资源,WPF资源系统提供的对象资源有如下好处: 1.  高效:使用对象资源可以在一个地方定义而 ...

  4. Windows App开发之经常使用控件与应用栏

    控件的属性.事件与样式资源 怎样加入控件 加入控件的方式有多种,大家更喜欢以下哪一种呢? 1)使用诸如Blend for Visual Studio或Microsoft Visual Studio X ...

  5. WPF教程十一:简单了解并使用控件模板

    WPF教程十一:简单了解并使用控件模板 这一章梳理控件模板,每个WPF控件都设计成无外观的,但是行为设计上是不允许改变的,比如使用Button的控件时,按钮提供了能被点击的内容,那么自由的改变控件外观 ...

  6. Windows常见窗口样式和控件风格

    Windows常见窗口样式和控件风格 王佰营 徐丽红 一.窗口样式 WS_POPUP 弹出式窗口(不能与WS_CHILDWINDOW样式同时使用)WS_CHILDWINDOW 子窗口(不能与WS_PO ...

  7. 与众不同 windows phone (52) - 8.1 新增控件: AutoSuggestBox, ListView, GridView, SemanticZoom

    [源码下载] 与众不同 windows phone (52) - 8.1 新增控件: AutoSuggestBox, ListView, GridView, SemanticZoom 作者:webab ...

  8. 快速构建Windows 8风格应用6-GridView数据控件

    原文:快速构建Windows 8风格应用6-GridView数据控件 本篇博文主要介绍什么是GridView数据控件.如何构建常用的GridView数据呈现样式. 什么是GridView数据控件? G ...

  9. SNF开发平台WinForm-Grid表格控件大全

    我们在开发系统时,会有很多种控件进行展示,甚至有一些为了方便的一些特殊需求. 那么下面就介绍一些我们在表格控件里常用的方便的控件:   1.Grid表格查询条 Grid表格下拉 3.Grid表格弹框选 ...

随机推荐

  1. 【PHP SDK for OpenStack/Rackspace APIs】身份验证

    在你使用php-opencloud之前必须先取得云服务提供商的身份验证.这是整个过程中最简单也是最让人沮丧的部分. 说它最简单是因为你只需要两部分信息: 云服务提供商的身份验证端点 用来身份验证的证书 ...

  2. struts 2吊牌s:if 、s:iterator注意

    疏忽,也没有相应的总结.实际上JSTL标签Struts2标签混淆.导致一些上述问题的细节.今天我给从下一个总结,同 后不要再犯这种错误. 总喜欢在s:if标签里面使用$,导致各种数据读不出来. str ...

  3. Android Studio之同一窗口打开项目

    Android Studio默认新打开的项目都是重新打开一个窗口,和原项目窗口同时存在,如果打开多个项目,则有很多窗口同时打开,怎么根据需要决定自己以何种方式打开呢? 1.设置打开新项目的方式 第一项 ...

  4. Using Qt to build an Omi App for iOS (and Android)

    JUNE 6, 2014 / HHARTZ Working on projects where the technology is pre-determined, it's often difficu ...

  5. HDU 4921 Map

    题意: 给n个节点  他们形成了最多10条链  每条最多1000的长度  每一个节点有个val  你能够选择任何位置截断链  断点前的全部节点被你获得  通过题中计算公式得出你的val  问  通过随 ...

  6. 【BASH】自己主动清理rman脚本备份文件

    ************************************************************************ ****原文:blog.csdn.net/clark_ ...

  7. OCP读书笔记(7) - 使用RMAN执行恢复

    7.Using RMAN to Perform Recovery 使用RMAN进行完全恢复system表空间文件丢失的恢复 模拟损坏: SQL> conn /as sysdba; SQL> ...

  8. [cocos2d-x]屏幕自适应解决的方法

    近期在写一个项目,要求pc,ipad,andriod平台上都能够执行,所以选择用cocos2d-x来开发. 我们的资源大小是1024*768的,在pc上和苹果上都是没有问题的,但是到了andriod上 ...

  9. selenium让人摸不着头脑的问题

    selenium让人摸不着头脑的问题 问题一 使用webdriver驱动firefox浏览器时如果不设置参数,默认使用的Firefox的profile和平时打开浏览器使用的firefox不一样,如果要 ...

  10. WPF案例 (六) 动态切换UI布局

    原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...