Beginning Silverlight 4 in C#-Silverlight控件

设置控件属性

最简单直接设置属性的方法是使用特性(attribute)句法.但是,在某些情况,只能用元素(element)句法.

特性句法

大部分的属性可以使用特性句法以一个简单的字符串形式表现.在XAML设置一个特性就好像是在XML里设置一个特性.一个XML元素包含一个节点和一些特性.Silverlight控件以相同的方式定义,控件名是节点,属性以特性(attributes)的方式定义.

例如,你可以简单地使用特性句法设置一个按钮控件的Width,Height和Content属性,如下:

<Button Width="100" Height="30" Content="Bottom Right"></Button>

元素句法

元素句法是当属性值不能用特性句法的简单的字符串表达时使用.还有,它与XML中的元素非常相似.下面的例子展示给一个按钮添加背景元素:

<Button Width="100" Height="30" Content="Click Me!">
    <Button.Background>
        <SolidColorBrush Color="Blue"/>
    </Button.Background>
    <Button.Foreground>
        <SolidColorBrush Color="Red"/>
    </Button.Foreground>
</Button>

可类型转换特性(Type-Converter-Enabled Attributes)

某些时候,当通过特性定义属性时,属性值不能用简单的字符串表达,它会转换为一个复合的类型.一个简单的可类型转换特性的例子就是Margin.这个Margin属性可以可以被设为一个简单的字符串,例如:

<Button Width="100" Height="30" Content="Click Me!" Margin="15"/>

当你以这样的形式设置Margin属性时,左,右,上和下的Margin都会设为15px.如果你只想设置上Margin为15px,其它为0,怎么办呢?如下:

<Button Width="100" Height="30" Content="Click Me!" Margin="0,15,0,0"/>
这里Silverlight会取出字符串"0,15,0,0"同时把它转换为一个复合的类型.这个字符串会转换为4个值:left margin = 0, top margin = 15, right margin = 0, 和bottom margin = 0. 

附属属性

在上一篇文章,你学习了怎样使用附属属性设置一个控件在Canvas里的位置.一个附属属性是一个附属于父控件的属性.在上一篇文章的例子里,你通过设置两个属性指定按钮控件在Canvas对象里的位置:Canvas.Top和Canvas.Left.这两个属性附属于按钮控件的父控件Canvas.

<Button Width="100" Height="30" Content="Button 2" Canvas.Left="10" Canvas.Top="40" />

控件嵌套控件

当你第一次看到Silverlight2包含的控件时,你可能感到份外亲切,它们看起来就像期望的那样.但是当你仔细研究控件的特性,你会发现控件比你看它的第一眼的感觉要复杂得多.

Silverlight 2的一个最关键的特性是可以放任何东西到一个控件里.一个按钮控件可以包含一个StackPanel,这个StackPanel又可以包含一个Ellipse和一个TextBlock.一个控件的内容(Contents)可以是什么有一些限制.下面展示一个标准的Silverlight 2按钮包含一个StackPanel,一个嵌套的StackPanel,一个Ellipse,一个TextBlock,和一个ListBox.

image

<Button Height="180" Width="200">
    <StackPanel Orientation="Vertical">
        <StackPanel Margin="5" VerticalAlignment="Center" Orientation="Horizontal">
            <Ellipse Fill="Yellow" Width="25" />
            <TextBlock VerticalAlignment="Center" Margin="5" Text="Check Forecast" />
        </StackPanel>
        <ListBox FontSize="11" Opacity="0.5" Margin="2" x:Name="lstForecastGlance">
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Mon: Sunny (85)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Tue: Partly Cloudy (89)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Wed: Thunderstorms (78)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Thu: Thunderstorms (76)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Fri: Partly Cloudy (71)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Sat: Mostly Sunny (74)" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock VerticalAlignment="Center" Text="Sun: Sunny (80)" />
            </ListBoxItem>
        </ListBox>
    </StackPanel>
</Button>

正如代码所示,这个例子简单地嵌套一些内容到一个按钮里.正如你所想的,这是一个非常强大的特性.

在Silverlight里处理事件

在为另一个Microsoft的编程框架,Silverlight提供一个事件机制来跟踪发生在应用程序里的actions.两类的actions会被跟踪:

  • 基于一些来自用户的输入而被触发的actions.输入actions会被处理和会从浏览器到Silverlight对象模型向上"冒泡".
  • 基于一个特定的对象的状态变化而触发的actions,包括在应用程序里的对象的状态.这些actions会从Silverlight对象模型里立即处理.

事件处理程序是一些当被触发时立即运行的方法.你即可以通过XAML标记本身定义,也可以在托管代码里定义.下面的练习会显示展示两种方式定义事件处理程序.

在XAML里声明事件

  1. 使用VS2010创建一个名为EventHandlers的Silverlight应用程序.
  2. 为根表格添加4行,2列.
  3. 接着,添加一个按钮到左上单元格,一个TextBlock到右上单元格.
  4. 为这个按钮添加一个Click属性.当你输入到"Click="时,VS会自动提示一个选项来添加一个新的事件处理程序.如下所示.当<新建事件处理程序>选择出现事,按下Enter键,VS就会完成Click属性.
    image代码如下:
    <Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="70" />
            <RowDefinition Height="70" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
            <Button  Width="125" Height="35" Content="XAML Event" Click="Button_Click"/>
        <TextBlock Text="Click the XAML Event!" Grid.Column="1" VerticalAlignment="Center"  HorizontalAlignment="Center" />
    </Grid>
    
    另外,VS会自动为Silverlight应用程序添加一个名为Button_Click的事件处理程序到后置代码类里,如下:
    public partial class MainPage : UserControl
    {
        public MainPage() {
            InitializeComponent();
        }
    
        private void Button_Click(object sender, RoutedEventArgs e) {
    
        }
    }
  5. 在这个例子里,你会改变TextBlock的Text属性.为了做到这点,你首先要给TextBlock一个name属性,如下:
    <TextBlock Name="txtXAMLEventText" Text="Click the XAML Event!" Grid.Column="1" VerticalAlignment="Center"  HorizontalAlignment="Center" />
    
  6. 现在在Button_Click事件里改变TextBlock控件的Text属性:
    private void Button_Click(object sender, RoutedEventArgs e) {
        txtXAMLEventText.Text = "现在的时间是:" + DateTime.Now.ToString();
    }
  7. 运行程序,点击按钮.会显示当前的时间.如下:
    image

通过托管代码声明事件处理程序

继续在这个项目里练习.

  1. 添加一个按钮到根表格控件的第二行.
  2. 要在托管代码里引用新的按钮和TextBlock,你就必须给他们一个name属性,如下:
    <Button Name="btnManaged" Width="125" Height="35" Content="Managed Event" Grid.Row="1" /> 
          
    <
    TextBlock Name="txtManagedEventText" Text="Click the Managed Event!" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" />
  3. 接着,右击页面,选择"查看代码".这会转换到后置代码页面.
    到这里,你会使用标准的CLR语言来添加事件处理程序.因为你使用的是C#,语法是使用"+="操作符,给它分配一个新的EventHandler.VS会帮助你完成这些.完成后代码如下:
    public MainPage() {
        InitializeComponent();
        this.btnManaged.Click += new RoutedEventHandler(btnManaged_Click);
    }
    
    static int i = 0;
    void btnManaged_Click(object sender, RoutedEventArgs e) {
        this.txtManagedEventText.Text = i.ToString();
        i++;
    }
  4. 运行代码,结果如下:
    image

这个练习显示了怎么使用C#和托管代码定义事件处理程序.

在剩下的部分,我们浏览一遍Silverlight较为常用的表单控件.

Border控件

Border控件为Silverlight的任何一个控件提供一个方法来添加一条边线和背景.尽管每个控件多会有一个Border,你也总是可以放置一个Border到一个StackPanel里,或者放到一个Grid里,结果就是多了一个Border.

添加一个Border到你的Silverlight应用程序是非常简单的,看下面的例子:

<Grid x:Name="LayoutRoot" Background="White">
    <Border BorderThickness="2" BorderBrush="Black" Margin="10">
        <StackPanel Margin="10">
            <Button Content="Sample Button" Margin="5" />
            <TextBlock Text="Sample TextBlock" Margin="5" />
            <ListBox Margin="5">
                <ListBoxItem>
                    <TextBlock Text="ListItem 1" />
                </ListBoxItem>
                <ListBoxItem>
                    <TextBlock Text="ListItem 2" />
                </ListBoxItem>
                <ListBoxItem>
                    <TextBlock Text="ListItem 3" />
                </ListBoxItem>
                <ListBoxItem>
                    <TextBlock Text="ListItem 4" />
                </ListBoxItem>
            </ListBox>
        </StackPanel>
    </Border>
</Grid>

效果如图:

image

Border控件的另一个特性是能使用CornerRadius属性做出圆角效果:

<Border BorderThickness="2" BorderBrush="Black" Margin="10" CornerRadius="10">

效果如图:

image

你可以使用Background属性定义背景颜色.就像BorderBrush属性,Background属性可以设为一个颜色,可以设为一个brush类.下面是使用Brush对象设置Border的Background的例子:

<Border BorderThickness="2" Margin="10" CornerRadius="10">
        <Border.Background>
            <LinearGradientBrush>
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="Green" Offset="0" />
                    <GradientStop Color="White" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Border.Background>
        <Border.BorderBrush>
            <LinearGradientBrush>
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="White" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Border.BorderBrush>
        <StackPanel Margin="10">
        <Button Content="Sample Button" Margin="5" />
        <TextBlock Text="Sample TextBlock" Margin="5" />
        <ListBox Margin="5">
            <ListBoxItem>
                <TextBlock Text="ListItem 1" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="ListItem 2" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="ListItem 3" />
            </ListBoxItem>
            <ListBoxItem>
                <TextBlock Text="ListItem 4" />
            </ListBoxItem>
        </ListBox>
    </StackPanel>
</Border>

效果如下:

image

扩展控件

-当一个Silverlight应用程序被部署时,它会打包为一个.xap文件.这个文件需要被每个客户端下载才能访问这个Silverlight应用程序.

Silverlight程序的一个优点是.xap文件的size总是很小的.其中一个原因是大部分的用户控件已包含在Silverlight运行时里.

然而,Silverlight在普通控件集合的基础上提供了一些控件.这些控件分别在两个程序集里:System.Windows.Controls.dll和System.Windows.Controls.Data.dll.只有开发者使用了这些程序集的控件时,这些DLLs会被包含进.xap文件.

添加一个扩展控件

当开发者使用其它控件类库的控件时,要在UserControl定义里添加一个xmlns声明.这个xmlns会有一个关联的前缀用于在后面引用那些特别的控件.例如,如果你在VS里为你的Silverlight应用程序里添加一个DataGrid控件,源码会像如下所示:

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:DataGrid AutoGenerateColumns="False" Name="dataGrid1" />
    </Grid>
</UserControl>

试试看:使用GridSplitter

一个在 System.Windows.Controls程序集里的控件是GridSplitter.这个控件提供用户可在应用程序里改变行或列宽度的能力.如果使用属性,GridSplitter会极大地改进你的应用程序的外观和用户体验.接下来的练习,你会实现一个简单的GridSplitter.

  1. 使用VS2010创建一个名为GridSplitterControl的Silverlight应用程序.
  2. 在根表格控件里定义2列.第一列150px宽,第二列暂满剩余空间.设置ShowGridLines为True.添加两个TextBlock控件,一个在第一列,一个在第二列,源码如下:
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
    
        <TextBlock Text="Apress, Inc." />
        <TextBlock Grid.Column="1" Text="Beginning Silverlight 4: From Novice to Professional" />
    </Grid>
    
    效果如图:
    image注意你不能看到第二列所有的文本.
  3. 双击VS工具箱的GridSplitter添加控件,,到页面的设计视图里右击GridSplitter控件选择"重置布局"=>"全部"
    <sdk:GridSplitter Background="LightGray"  Name="gridSplitter1" />
    
  4. 运行程序,效果如下:
    image
posted @ 2011-12-16 02:26  zhangweiwen  阅读(1167)  评论(3编辑  收藏  举报