【WindowsPhone】--(三)数据绑定&上
一、概述
1、数据绑定为WP7应用程序提供了一种简单的数据呈现与交互过程。数据绑定的过程是目标的依赖属性和数据源属性的握手过程。
2、绑定对象:Binding Target,必须是一个 Dependency Property 并且继承自 FrameworkElement
绑定数据源:Binding Source,只需要是一个 CLR Object
二、建立数据绑定
1、在XAML中建立数据绑定,下面通过一个呈现天气的例子来看看建立数据绑定的过程
(1)确定数据源
创建一个存放图片数据的类 Wether.cs
namespace DataBinding { public class Wether { //绑定源属性 public Uri pSource {get ;set ;} public string pName { get; set; } } }
(2)确定绑定目标,在 MainPage.xaml 中,添加控件:一个TextBlock、一个Image、一个Button,代码如下:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Image Source="{Binding pSource}" Height="194" HorizontalAlignment="Left" Margin="57,73,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="248" /> <TextBlock Text="{Binding pName}" Height="45" HorizontalAlignment="Left" Margin="77,301,0,0" Name="textBlock1" VerticalAlignment="Top" Width="145" /> <Button Content="其他天气" Height="72" HorizontalAlignment="Left" Margin="145,425,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" /> </Grid>
(3)实例化绑定源。借助于绑定目标控件的 DataContent 属性,接受数据源上各种可供使用的数据,DataContent 属性能够让子元素分享父元素的数据项。
代码如下:(先新建一个名为“Picture”的文件夹,把图片粘贴到文件夹中)
//天气1 Wether wether1 = new Wether { pSource = new Uri("/Picture/1.png", UriKind.RelativeOrAbsolute), pName = "晴天" }; //天气2 Wether wether2 = new Wether { pSource = new Uri("/Picture/2.png", UriKind.RelativeOrAbsolute), pName = "晴转雨夹雪" }; this.LayoutRoot.DataContext = wetherSequence; //LayoutRoot是Grid的父容器,这里用来显示更新后的数据
(4)Mode下默认的是单项数据绑定OneWay,因此这个项目也是一个单向的数据绑定。接着给 Button 添加更改绑定源的事件,代码:
实现代码第一种方式:(不用添加命名空间 Using System.Windows.Data)
namespace DataBinding { public partial class MainPage : PhoneApplicationPage { private Wether wether1; private Wether wether2; private Wether wetherSequence; // 构造函数 public MainPage() { InitializeComponent(); //天气1 wether1 = new Wether { pSource = new Uri("/Picture/1.png", UriKind.RelativeOrAbsolute), pName = "晴天" }; //天气2 wether2 = new Wether { pSource = new Uri("/Picture/2.png", UriKind.RelativeOrAbsolute), pName = "晴转雨夹雪" }; wetherSequence = wether1; this.LayoutRoot.DataContext = wetherSequence; } private void button1_Click(object sender, RoutedEventArgs e) { if (wetherSequence == wether1) { wetherSequence = wether2; } else wetherSequence = wether1; this.LayoutRoot.DataContext = wetherSequence; //LayoutRoot是Grid的父容器,这里用来显示更新后的数据 } } }
实现代码的第二种方式:(在命名空间中添加一个 using System.Windows.Data ,因为 Binding 在这个命名空间下,然后在 button1_Click 中写入以下代码)
private void button1_Click(object sender, RoutedEventArgs e) { //绑定图片 Binding bdPicture = new Binding(); bdPicture.Source = wether1; bdPicture.Path = new PropertyPath("pSource"); this.image1.SetBinding(Image.SourceProperty, bdPicture); //绑定信息 Binding bdName = new Binding(); bdName.Source = wether; bdName.Path = new PropertyPath("pName"); this.textBlock1.SetBinding(TextBlock.TextProperty, bdName); }
2、可以在属性面板中建立数据绑定
以 Slider 的值的改变控制着 TextBlock 中字体的大小值的改变为例子,需要两步:
(1)在属性面板中选择绑定目标,并确定依赖属性;
绑定目标 TextBlock 的依赖属性 FontSize 菜单中的 Apply Data Binding
(2)选择绑定源属性。
选择数据源属性为 Slider 控件的 Value 属性,展开 “Source” 列表,选择“ElementName”项,再选择所包含的“Slider1”的值,接着展开“Path”列表,选择“Value”就ok了。
在xaml中显示的属性为:
<TextBlock FontSize="{Binding ElementName=slider1,Path=Value}" ... />
3、绑定数据模式(重点)
Mode用于指定目标控件与数据源之间的同步方式,有3个值:
OneTime:目标控件只更新一次,以后的更新会被忽略
OneWay: 数据对象的值同步更新到目标控件的属性,但反过来是不行的。相当于一次绑定,不能操作数据
TwoWay: 数据对象的值和目标控件的属性是同步的,这是经常用到的模式
要将Mode设置为OneWay或TwoWay,需要遵循:必须继承于 INotifyPropertyChanged 接口;绑定目标或者数据源有变化时,需要使用 INotifyPropertyChanged通知对象数据有更新;INotifyPropertyChanged事件函数捕获到绑定源被修改时,将会返回被修改后的数据。
下面是一个仍以显示天气信息为例子,在 xaml 中需要添加一个 TextBox 控件,用来更新数据
(1)在Wether.cs中绑定数据源,继承于INotifyPropertyChanged接口
需要先添加 INotifyPropertyChanged 所在的命名空间 Using System.ComponentModel,
namespace DataBinding { //绑定源必须继承于INotifyPropertyChanged public class Wether:INotifyPropertyChanged //鼠标右击INotifyPropertyChanged,会显示一个实现接口的提示,点击实现就会显示出下面的接口 { //绑定源属性 private Uri pSource { get; set; } private string pName; private string pNames { get { return pName; } set{ pName=value; INotifyPropertyChanged("pNames"); } } public event PropertyChangedEventHandler PropertyChanged; //数据源绑定属性发生改变,执行更新通知事件,并返回被更新过的数据 private void INotifyPropertyChanged(string p) //自己封装成INotifyPropertyChanged { if (PropertyChanged!=null) { PropertyChanged(this, new PropertyChangedEventArgs(p)); } } /*上述代码解析:PropertyChanged是返回被更新后的数据,使用一个自定义的函数名INotifyPropertyChanged 来简化其重复代码,函数INotifyPropertyChanged会传出一个事件参数PropertyChangedEventArgs来通知 绑定源属性绑定目标属性已经发生了改变,而 INotifyPropertyChanged("pNames")中的属性pNames就是 绑定源中的绑定数据源属性,作为一个参数来传数据。*/
//绑定源属性 public Wether(Uri pSourcex, string pNamex) { pSource = pSourcex; pNames = pNamex; } } }
(2)实例化数据,并将数据分享
同样的,需要将绑定数据源中的绑定属性通过 DataContext 属性分享给绑定目标的显示控件,最后在绑定目标中指定绑定依赖属性。
下面是 MainPage.xaml.cs 中的代码:
namespace DataBinding { public partial class MainPage : PhoneApplicationPage { public Wether pName1; public MainPage() { InitializeComponent(); pName1 = new Wether((new Uri("/Picture/2.png", UriKind.RelativeOrAbsolute)), "晴天有小雪"); this.LayoutRoot.DataContext = pName1;
//更新按钮的Click事件 button1.Click += new RoutedEventHandler(button1_Click); } void button1_Click(object sender, RoutedEventArgs e) { pName1.pNames = textBox1.Text; } } }
(3)当然还要整理下前台代码
<!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Image Source="{Binding pSources}" Height="194" HorizontalAlignment="Left" Margin="57,73,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="248" /> <TextBlock Text="{Binding pNames}" Height="45" HorizontalAlignment="Left" Margin="77,301,0,0" Name="textBlock1" VerticalAlignment="Top" Width="145" /> <Button Content="更新天气信息显示" Height="72" HorizontalAlignment="Left" Margin="43,485,0,0" Name="button1" VerticalAlignment="Top" Width="262" Click="button1_Click" /> <TextBox Height="72" HorizontalAlignment="Left" Margin="12,379,0,0" Name="textBox1" Text="{Binding pNames}" VerticalAlignment="Top" Width="412" /> </Grid>
运行结果如下图1:
<<--- 图1 <<--- 图2
当然可以在文本框中更新该天气的文字显示信息,如上图2
-- 后记:关于wp的一些基础,和朋友分享下,这篇数据绑定还有下文呢,@_@