Silverlight4Beta之Binding的新特性(上)

Silverlight4中针对数据绑定(Binding)又有所增强,使得silverlight向强大的wpf又接近了一步。下面就让我们盘点一下Silverlight4Beta中有关Binding的新特性。

StringFormat Binding

StringFormat Binding在WPF很常见,在处理一些细节问题时会省事不少,现在Silverlight也拥有它了,他的用法等同于.Net框架中常用的

String.Format()

 

现在模拟一个典型场景,假设我们拥有一个数据实体Customer,它的定义如下:

    public class Customer {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
        public decimal BankBalance { get; set; }
    }

然后我们将其设置为MainPage的DataContext

    public partial class MainPage : UserControl {
        public MainPage() {
            InitializeComponent();

            this.Loaded += (s, e) => {
                  this.DataContext = new Customer() {
                      FirstName = "紫色永恒",
                      LastName = "于",
                      BankBalance = 250000.0m,
                      DateOfBirth = DateTime.Now
                  };
              };
        }
    }

准备工作完毕后,我们在UI上了使用StringFormat Binding:

<UserControl x:Class="SilverlightApplication20.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">

    <Grid x:Name="LayoutRoot" Background="White">
        <Viewbox>
            <StackPanel>
                <TextBlock
                    Text="{Binding FirstName}" />
                <TextBlock
                    Text="{Binding LastName}" />
                <TextBlock
                    Text="{Binding Path=DateOfBirth,StringFormat=生日: \{0:D\}}" />
                <TextBlock
                    Text="{Binding Path=BankBalance,StringFormat=存款: \{0:C\}}" />
            </StackPanel>
        </Viewbox>
    </Grid>
</UserControl>

F5运行后

image

说真的,StringFormat在MultiBinding的场景中更加有用,可惜Silverlight尚不支持多重绑定。

FallbackValue Binding

先解释一下Fallback这个词,摘录于有道词典:

【计算机】退却(计算机在发生故障时,即使系统的一部分功能降低但仍能保持主要功能)

 

好了,这下清楚了,当绑定到UI的某些属性抛出异常时我们可以通过FallbackValue Binding统一处理其显示的值,我们简单修改一下刚才的实体类:

    public class Customer {
        public string FirstName {
            get {
                throw new NotImplementedException("Sorry");
            }
            set {
            }
        }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
        public decimal BankBalance { get; set; }
    }


显而易见,当我们要得到FirstName的值时,必定抛出异常

然后修改我们的XAML:

   <Grid x:Name="LayoutRoot" Background="White">
        <Viewbox>
            <StackPanel>
                <TextBlock
                    Text="{Binding FirstName, FallbackValue=N/A}" />
                <TextBlock
                    Text="{Binding LastName,FallbackValue=N/A}" />
                <TextBlock
                    Text="{Binding Path=DateOfBirth,StringFormat=Date of Birth: \{0:D\}}" />
                <TextBlock
                    Text="{Binding Path=BankBalance,StringFormat=Balance: \{0:C\}}" />
            </StackPanel>
        </Viewbox>
    </Grid>

F5运行:

image

即FirstName显示为FallbackValue所设置的“N/A”

TargetNullValue Binding

与FallbackValue类似,TargetNullValue用来处理当某个属性是Null时UI所呈现的值:

继续折磨我们的Customer类

    public class Customer {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime? DateOfBirth {
            get {
                return (dateOfBirth);
            }
            set {
                dateOfBirth = value;
            }
        }
        public decimal BankBalance { get; set; }

        DateTime? dateOfBirth;
    }

我们增加了一个可空DateTime类型的属性DateOfBirth。可以预见的是,在对其Set之前,它将返回null。

再次改动XAML如下:

        <Grid x:Name="LayoutRoot" Background="White">
            <Viewbox>
                <StackPanel>
                    <TextBlock Text="{Binding FirstName,StringFormat=:\{0\}}" />
                    <TextBlock Text="{Binding LastName,StringFormat=:\{0\}}" />
                    <TextBox Text="{Binding Path=DateOfBirth,TargetNullValue=未填,StringFormat=DOB:\{0\},Mode=TwoWay}" />
                    <TextBlock Text="{Binding Path=BankBalance,StringFormat=存款:\{0\}}" />
                    <Button Content="Save" />
                </StackPanel>
            </Viewbox>
        </Grid>

如XAML所示,DateOfBirth被绑定到一个TextBox上。我们设置其TargetNullValue为“N/A”,为了实验TargetNullValue的效果,我们还要修改MainPage的构造函数:

    public partial class MainPage : UserControl {
        public MainPage() {
            InitializeComponent();

            this.Loaded += (s, e) => {
                  this.DataContext = new Customer() {
                      FirstName = "Kermit",
                      LastName = "Frog",
                      BankBalance = 250000.0m,
                      DateOfBirth = null
                  };
              };
        }
    }

我们将DateOfBirth属性的初始值设定为null,这样我们就可以在UI中看到TargetNullValue的效果(注意这里为了方便起见,我并没有为实体类实现INotifyPropertyChanged,偷个懒嘿嘿)

F5运行

imagenull       image非null

如非null那张图所示,我们输入一个确切的日期,在后台代码中我们可以正确的接收到这个日期

image

如果在TextBox输入“N/A”呢?

image

看,null被传回了:

image

 

综上所述,TargetNullValue尤其适用于从数据库获取数据并处理空值的场景。

posted @ 2009-12-06 21:18  紫色永恒  阅读(1792)  评论(1编辑  收藏  举报