一步一步学Silverlight 2系列(9):使用控件模板

概述

Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ironpython,对JSON、Web Service、WCF以及Sockets的支持等一系列新的特性。《一步一步学Silverlight 2系列》文章带您快速进入Silverlight 2开发。

本文为系列文章第九篇,主要介绍如何使用控件模板定制控件的观感。Silverlight提供了极其强大的功能,允许用户完全定制控件的外观。

定制控件内容

在Silverlight中,WatermarkedTextBox控件可以为用户的输入提供一段提示信息,如果只是简单的一点文字信息,有时候未免显得单调,如果加上相应的图片说明效果会更好,如下图所示的一个简单的用户登录界面:

TerryLee_Silverlight2_0045

这样看起来界面显的就生动多了,XAML声明如下:

<Canvas Background="#46461F">
    <WatermarkedTextBox x:Name="UserName" Canvas.Top="30" Canvas.Left="50"
                        Width="320" Height="48">
        <WatermarkedTextBox.Watermark>
            <StackPanel Width="320" Height="48" Orientation="Horizontal">
                <Image Source="admin.png" HorizontalAlignment="Left"></Image>
                <TextBlock Text="请输入用户名" VerticalAlignment="Center" Foreground="#999999"/>
            </StackPanel>
        </WatermarkedTextBox.Watermark>
    </WatermarkedTextBox>
    
    <WatermarkedTextBox x:Name="Password" Canvas.Top="110" Canvas.Left="50"
                        Width="320" Height="48" HorizontalAlignment="Left">
        <WatermarkedTextBox.Watermark>
            <StackPanel Width="320" Height="48" Orientation="Horizontal">
                <Image Source="lock.png" HorizontalAlignment="Left"></Image>
                <TextBlock Text="请输入密码" VerticalAlignment="Center" Foreground="#999999"/>
            </StackPanel>
        </WatermarkedTextBox.Watermark>
    </WatermarkedTextBox>
    
    <Button Canvas.Top="180" Canvas.Left="100"
            Width="120" Height="48">
        <Button.Content>
            <StackPanel Orientation="Horizontal">
                <Image Source="apply.png" HorizontalAlignment="Left"></Image>
                <TextBlock Text="登 录" VerticalAlignment="Center" Margin="10 0 0 0"></TextBlock>
            </StackPanel>
        </Button.Content>
    </Button>
</Canvas>

很多控件都有Content或者Text属性,我们完全可以充分发挥自己的想象力去进行定制,定制后控件仍然具有原来的功能行为,如上面的示例,当输入用户名控件获得焦点时文字和图片都将消失:

TerryLee_Silverlight2_0046

使用控件模板定制控件

前面的示例中我们只是定制了控件的内容,Silverlight允许我们完全对控件进行定制,而不仅仅是内容。下面的示例中我们定制一个渐变色的圆角矩形按钮。首先我们在App.xaml中创建一个RoundButton样式,改写按钮的Template属性:

<Style x:Key="RoundButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootElement">
                    <Rectangle Width="200" Height="80" RadiusX="15" RadiusY="15">
                        <Rectangle.Fill>
                            <LinearGradientBrush StartPoint="0,0">
                                <GradientStop Color="#FFFFFF" Offset="0.0" />
                                <GradientStop Color="#EC04FA" Offset="1.0" />
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                        <Rectangle.Stroke>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FCB2FD" Offset="0" />
                                <GradientStop Color="#FFFFFF" Offset="1" />
                            </LinearGradientBrush>
                        </Rectangle.Stroke>
                    </Rectangle>
                    <TextBlock Text="提 交" FontSize="26" Foreground="White"
                               HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

其中的渐变等内容在Graphics相关内容里将会写到。现在在XAML中使用该样式:

<Canvas Background="#46461F">
    <Button x:Name="button1" Style="{StaticResource RoundButton}"
            Canvas.Top="80" Canvas.Left="150"/>
</Canvas>

运行后就可以看到下面的效果:

TerryLee_Silverlight2_0047

创建模板

上面的示例中,控件的文字以及控件的大小都是固定的,我们希望在开发人员使用中再设定,可以在控件模板中通过使用 {TemplateBinding ControlProperty} 的标识扩展句法来绑定到控件的属性来实现,使用ContentPresenter控件可以灵活的设置各个属性。修改RoundButton样式如下所示:

<Style x:Key="RoundButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootElement">
                    <Rectangle Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
                               RadiusX="15" RadiusY="15">
                        <Rectangle.Fill>
                            <LinearGradientBrush StartPoint="0,0">
                                <GradientStop Color="#FFFFFF" Offset="0.0" />
                                <GradientStop Color="#EC04FA" Offset="1.0" />
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                        <Rectangle.Stroke>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#EC04FA" Offset="0" />
                                <GradientStop Color="#FFFFFF" Offset="1" />
                            </LinearGradientBrush>
                        </Rectangle.Stroke>
                    </Rectangle>
                    <ContentPresenter
                        Content="{TemplateBinding Content}"
                        FontSize="{TemplateBinding FontSize}"
                        HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                        Foreground="{TemplateBinding Foreground}">
                    </ContentPresenter>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这样在使用RoundButton时我们可以设定控件的文本及控件的大小:

<Canvas Background="#46461F">
    <Button x:Name="button1" Style="{StaticResource RoundButton}"
            Canvas.Top="80" Canvas.Left="50"
            Content="提 交" FontSize="26"
            HorizontalContentAlignment="Center"
            VerticalContentAlignment="Center"
            Foreground="White" Width="200" Height="60"/>
    
    <Button x:Name="button2" Style="{StaticResource RoundButton}"
            Canvas.Top="80" Canvas.Left="260"
            Content="取 消" FontSize="26"
            HorizontalContentAlignment="Center"
            VerticalContentAlignment="Center"
            Foreground="White" Width="100" Height="100"/>
</Canvas>

运行时效果如下:

TerryLee_Silverlight2_0048

结束语

本文简单的介绍了如何定制控件的内容以及通过控件模板完全定制控件,你可以从这里下载本文示例代码。

下一篇:一步一步学Silverlight 2系列(10):使用用户控件

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
标签: Silverlight, XAML
posted @ 2008-03-08 17:07 TerryLee 阅读(22816) 评论(55) 编辑 收藏

真快,高效率
TerryLee,这些控件都是公开了代码的有没有看过
 回复 引用 查看   
#3楼[楼主] 2008-03-08 17:30 TerryLee      
@自由、创新、研究、探索……
呵呵,周末没事,就看看Silverlight 2了:)

还没有看过。。。

 回复 引用   
#4楼 2008-03-08 17:46 TryHayyp[未注册用户]
TerryLee您好,这些例子照着做起来感觉不难,不过我有点疑问,就是它们如何应用在网页中,譬如我一个页面只是局部的某个地方像用silverlight,可以吗?请问怎么实现?
 回复 引用   
#5楼 2008-03-08 17:59 TryHayyp[未注册用户]
不好意思,刚下了你的代码,现在大致知道了,这样理解对吗:
在silverlight项目中建立好以后,然后在在页面中引用:<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TerryLee.SilverlightDemo20.xap" Version="2.0" Width="100%" Height="100%" />

但是如果我在silverlight项目中建立了2个页面:Page.xaml、Page2.xaml,如何知道引用的是哪一个页面啊?
谢谢

 回复 引用   
#6楼 2008-03-08 18:04 TryHayyp[未注册用户]
能不能写一篇如何在页面中使用的小例子啊,譬如说简单的提交信息的小sample
 回复 引用   
#7楼 2008-03-08 18:10 gakaki[未注册用户]
我看我们去CODEPLEX开个SILVERLIGHT 控件项目算了 吸取市面上所有商业的 开源的控件 EXT啦 RAD啦 之类的控件 对整个ajax 控件来个 大替换
 回复 引用 查看   
#8楼[楼主] 2008-03-08 18:21 TerryLee      
@TryHayyp
是的,在页面中除了添加控件之外,你也可以添加其它的ASP.NET中的控件。

在一个Silverlight项目中,只能有一个启动页面,如果有两个页面,可以在App.xaml的Application_Startup方法中,设置RootVisual来指定启动页面。

 回复 引用 查看   
#9楼[楼主] 2008-03-08 18:22 TerryLee      
@TryHayyp
类似的小例子后面会写到,一下子写不了那么多啊,今天写的快累死了,呵呵:)

 回复 引用 查看   
#10楼[楼主] 2008-03-08 18:22 TerryLee      
@gakaki
这个想法不错哦,呵呵

 回复 引用 查看   
#11楼 2008-03-08 19:03 王德水      
支持,TerryLee辛苦了
 回复 引用 查看   
#12楼[楼主] 2008-03-08 19:11 TerryLee      
@王德水
:)

 回复 引用   
#13楼 2008-04-18 14:00 未明明[未注册用户]
请问楼主如何实现密码框...
 回复 引用   
#14楼 2008-04-19 15:31 Parfum[未注册用户]
@未明明
这个应该可以用代码实现吧

 回复 引用   
#15楼 2008-05-09 12:41 问题多啊![未注册用户]
是啊,如何才能实现密码的输入呢?找了半天都没找到设置的属性!
 回复 引用 查看   
#16楼 2008-05-10 11:11 傻样精英      
我也想知道怎么搞密码框的属性呢,看到博主说用代码实现?
 回复 引用   
#17楼 2008-06-02 22:56 jeckbjy[未注册用户]
<Rectangle Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
不知可否设置默认值??

 回复 引用   
#18楼 2008-06-03 15:23 蒙[未注册用户]
说的有道理
 回复 引用 查看   
#19楼 2008-06-20 16:28 飄lá┽蕩去      
设置之后,按钮移上去没有高亮显示了
 回复 引用 查看   
#20楼[楼主] 2008-06-21 21:25 TerryLee      
@飄l&#225;┽蕩去
可以定制各种状态下的效果

 回复 引用 查看   
#21楼 2008-06-27 20:47 阿胜      
我在BETA 2 中没有使用<Rectangle Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"。好像也能重写Width,Height属性。
 回复 引用 查看   
#22楼[楼主] 2008-06-29 02:31 TerryLee      
@阿胜
这块在Beta 2中有些变化,请参考我的另外一篇关于升级到Beta 2的文章。

 回复 引用 查看   
#23楼 2008-07-30 11:38 阿无      
请问为什么我的silverlight里没有WatermarkedTextBox控件呢?其它的都有,就是没有WatermarkedTextBox
 回复 引用   
#24楼 2008-09-25 12:57 liugengshen[未注册用户]
WatermarkedTextBox为什么没有?
 回复 引用 查看   
#25楼[楼主] 2008-10-08 11:39 TerryLee      
@liugengshen
在Beta 2的时候移除了,将来会给TextBox提供一个Watermark的属性

 回复 引用 查看   
#26楼 2008-10-15 16:04 黄超      
在RTM版本没有Watermark属性?
 回复 引用   
#27楼 2008-11-25 16:27 silverlighter[未注册用户]
写的真不错、
 回复 引用 查看   
#28楼[楼主] 2008-12-01 00:06 TerryLee      
@黄超
微软没有添加。。。

 回复 引用 查看   
#29楼[楼主] 2008-12-01 00:06 TerryLee      
@silverlighter
谢谢:)

 回复 引用   
#30楼 2009-01-02 11:06 季风[未注册用户]
搁了两年的编程知识,今天重新来看一些知识,SilverLight2挺诱人的。请问在创建模板时,有没有其它办法?您现在介绍是纯手工敲打的
 回复 引用 查看   
#31楼[楼主] 2009-01-04 11:14 TerryLee      
@季风
可以使用Expression Blend来可视化实现。

 回复 引用   
#32楼 2009-02-19 10:54 aerolk[未注册用户]
ContentPresenter


SilverLight2 是不是改成 ContentControl 了?

 回复 引用   
#33楼 2009-04-20 11:39 desperado[未注册用户]
编译时报错:The property 'FontSize' was not found in type 'ContentPresenter'.

由于 ContentPresenter 现在从 FrameworkElement 派生,因此,以下属性不再由 ContentPresenter 公开:
FontSize、HorizontalContentAlignment、VerticalContentAlignment、Foreground

 回复 引用 查看   
#34楼 2009-05-18 10:58 徐培华      
watermarkedtextbox 在silverlight2.0里面没有吧?

 回复 引用 查看   
#35楼[楼主] 2009-05-18 11:10 TerryLee      
@徐培华
WatermarkedTextBox控件在Silverlight 2 RTW的时候已经移除了。

 回复 引用   
#37楼 2009-05-24 11:56 风生竹韵
楼主有没有发现,这样做了之后,那些按钮好像按了之后没有反应,虽然有消息发出来,但是样子完全不变。
 回复 引用 查看   
#38楼 2009-07-21 13:10 陈立东      
我用的sliverlight2_Tools 怎么没有atermarkedTextBox控件?很奇怪。。。
 回复 引用 查看   
#39楼 2009-07-21 13:11 陈立东      
我用的sliverlight2_Tools 怎么没有WatermarkedTextBox控件?很奇怪。。
 回复 引用   
#40楼 2009-08-10 21:26 4444444[未注册用户]
1114
 回复 引用   
#41楼 2009-08-10 21:35 22222222222[未注册用户]
';lkjhgfdsa[p;oliuytre
 回复 引用   
#42楼 2009-08-10 21:52 fffff[未注册用户]
a
 回复 引用   
#43楼 2009-08-10 21:54 SilverLight[未注册用户]

 回复 引用   
#44楼 2009-08-10 21:56 SilverLight[未注册用户]
非常好的教程
 回复 引用   
#45楼 2009-08-10 21:58 呵呵111[未注册用户]
5555555555555555555
 回复 引用 查看   
#47楼 2010-07-15 11:46 孤独求醉      
SL4,好像不能重写FontSize,FontFamily