Win8/WP8 XAML高级特性

Date 6/16/2014:

页面静态资源,如下:

    <Page.Resources>
        <Style x:Key="commonTextStyle" TargetType="TextBlock">
            <Setter Property="FontFamily" Value="Century Schoolbook" />
            <Setter Property="FontSize" Value="36" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="Margin" Value="12 12" />
        </Style>
        
        <Style x:Key="paragraphTextStyle" TargetType="TextBlock" BasedOn="{StaticResource commonTextStyle}">
            <Setter Property="TextAlignment" Value="Left" />
            <Setter Property="TextWrapping" Value="Wrap" />
        </Style>
        
        <Style x:Key="frontMatterTextStyle" TargetType="Image">
            <Setter Property="Stretch" Value="None" />
            <Setter Property="HorizontalAlignment" Value="Center" />
        </Style>
    </Page.Resources>
可以在<Page>节点下添加<Page.Resouces>子节点,定义本面页可以引用的静态资源,简而言之,当你的页面元素有类似的风格时即可定义这样一个静态资源,然后以属性的方式在页面元素中引用。页面元素也可重写引用资源的某些属性(这样势必会增加复杂性),更加强大的特性是其它静态资源也可以引用其它静态资源,这种效果类似于类的继承。静态资源的好处自然是减少代码量的同时支持高可修改性,可维护性。对静态资源的引用也很简单:

            <TextBlock Style="{StaticResource paragraphTextStyle}">
                  胖子和瘦子跋涉千里找到沙漠中的
                三叔,此时他已奄奄一息,瘦子赶紧扶起三叔。三叔用
                尽最后一点力气说:“叔渴,叔渴。”瘦子想了想,说:“
                舒克,舒克,开飞机的舒克!”三叔再度虚脱,瘦子眼见
                如此,对胖子说:“揹他,揹他!”胖子想了想,说:“贝
                塔,贝塔,开飞机的贝塔!”
            </TextBlock>

画布布局:

        <Canvas Name="canvas"></Canvas>
正如其名字所示,就是给你一个画布,可以在代码中对画布进行绘制。如绘制一个圆:

            Point pt = e.GetPosition(this);

            Ellipse ellipse = new Ellipse
            {
                Width = 3,
                Height = 3,
                Fill = this.Foreground
            };

            Canvas.SetLeft(ellipse, pt.X);
            Canvas.SetTop(ellipse, pt.Y);
            canvas.Children.Add(ellipse);

用户控件:

可以定义自己的页面元素类,其强大之处在于也支持XAML与CSharp结合的方式创建。这样就可以方便的先用XAML绘制好控件,动态的部分在代码中控制。如下自定义一个颜色卡片类:

<UserControl
    x:Class="Hello.ColorItem"
    mc:Ignorable="d"
    d:DesignHeight="144"
    d:DesignWidth="384">
    
    <Grid>
        <Border BorderBrush="AliceBlue" Height="100" Width="360" BorderThickness="2" Margin="12">
            <StackPanel Orientation="Horizontal">
                <Rectangle Name="rectangle" Width="72" Height="72" Margin="12" />
                <StackPanel VerticalAlignment="Center">
                    <TextBlock Name="textblockName" FontSize="24" />
                    <TextBlock Name="textblockRgb" FontSize="18" />
                </StackPanel>
            </StackPanel>
        </Border>
    </Grid>
</UserControl>

注意其根元素是<UserControl>,同时在构造函数中用颜色信息去初始化该控件:

public ColorItem(string name, Color clr)
        {
            this.InitializeComponent();
            rectangle.Fill = new SolidColorBrush(clr);
            textblockName.Text = name;
            textblockRgb.Text = String.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", clr.A, clr.R, clr.G, clr.B);
        }

这样,就可以在你的程序中方便地引用该控件,也可也方便地修改。

Grid布局:

网格布局可能是MS特有的布局,用起来也还可以,有两个非常有用的特性是:

一 可以定义网格列或行之间的宽度比值,而不用在指出其具体值,如下:

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
这个列定义,网格的三个列宽都是 “星号”,即不指定其特定值,但规定了三列宽度必须相等(都是“星号”),当然,也可以用 " 2* "来表示两倍宽等等。

二 网格之间可以合并,例如:

<span style="white-space:pre">	</span><Rectangle Name="colorPicked" Grid.Column="3" Grid.Row="0" Grid.RowSpan="3">
这里定义一个医形放在网格的第1行第四列,但其Grid.RowSpan指定其同时占用其下两个单元格,即合并了三个单元格。

合并单元格的效果可以用嵌套Grid来达到,但明显会复杂很多,不论是在编辑还是修改的时候。

数据绑定:

数据绑定功能强大,你可以绑定页面元素的属性值到类的属性,页面其它元素的属性甚至是JSON数据,这里以文本框绑定滑动条数值为例:

            <Slider Name="slider1" VerticalAlignment="Center"/>
            <TextBlock HorizontalAlignment="Center" FontSize="48" Text="{Binding ElementName=slider1, Path=Value}" />

将TextBlock的Text属性绑定到Slider的Value属性,这样当Slider的被拖动时,文本框也会自动更新其值,这里Slider的值是数据类型,而TextBlock的Text属性肯定是String类型,所以数据绑定时还隐式的做了类型转换。另一个情况是你可能需要自定义转换,你可以定编写一个Converter类,然后指定为TextBlock的Converter属性值。

其它类型的数据绑定仍待了解。

今天就行写到这里了,没图没真相,要真相打打代码。


Date 6/17/2014:

另一种常用的数据绑写则涉及到MVVM(Model-View-ViewModel)跟MVC差不多,都是把视图和逻辑分离,对于普通的如滑动条,可以使用实现INotifyChanged接口,里面的三个函数Execute, CanExecute, CanExecuteChanged 已经足够响应界面事件了,CanExecute返回响应是否可用,例如:按钮可不可以点击等等,将实现InotifyChanged接口的类定义为xaml页面的静态资源,就可以在页面中进行数据绑定了,对于Button则比较特殊,需要实现ICommand接口来实现绑定。

        <local:KeypadPage x:Key="keypadPage"/>

定义的ViewMode如上,KeypadPage就是实现了INotifyChanged的类,keypadPage就是在本页面的静态引用,如下,绑定KeypadPage类的一个成员:

<span style="white-space:pre">	</span><TextBlock Text="{Binding Source={StaticResource keypadPage}, Path=tip}" />

这样就绑定了KeypadPage类的tip成员,还有Mode选项可以选。

另外Page类还有一个DataContext作可作为默认的数据绑定源,语法更简单,即在Page初始化时this.DataContext = new KeypadPage();即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章