先用一個最簡單的例子來示範資料繫結。
建立一個項目TestData來測試,拖拽兩個控制項到螢幕上:TextBox和Slider。
給Slider的Name設定為slider1,然後我們給兩個控制項之間添加資料繫結,使得TextBox始終顯示滑動條內的進度值。
然後給Text屬性添加資料繫結,並且指定對象為slider1,完整代碼如下:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <TextBox HorizontalAlignment="Center" Margin="0,-100,0,0" TextWrapping="Wrap" Text="{Binding Value, Mode=TwoWay, ElementName=slider1}" VerticalAlignment="Center"/> <Slider x:Name="slider1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="30"/> </Grid>
啟動並執行結果就是1.拖動滑塊時文字框的數值也隨之改變2.文字框內容改變時捲軸也會跟著改變,這就是TwoWay:
那麼怎麼自己去寫資料繫結呢?
建立一個Person類來實驗一下。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace TestData{ class Person { public string Name { get; set; } public int Age { get; set; } }}
然後在首頁面拖拽一個TextBox和兩個按鈕,一個按鈕用來讀出Person的值,一個是用來修改Person的值:
先給TextBox命名為text1以便後面使用。
雙擊讀取的按鈕,跳轉到了背景c#檔案。
在類中聲明一個Person對象: Person myPerson = new Person();
然後在OnNavigatedTo方法中判斷,如果是NavigationMode.New則設定text1的DataContent為前面聲明的myPerson。
這裡可以把DataContent理解為資料來源。
然後點擊按鈕的監聽方法裡,將讀取到的Person內容顯示出來,在點擊第二個按鈕的時候將Person的name顯示為當前的毫秒數值。
完整的代碼如下:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using Windows.Foundation;using Windows.Foundation.Collections;using Windows.UI.Popups;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Controls.Primitives;using Windows.UI.Xaml.Data;using Windows.UI.Xaml.Input;using Windows.UI.Xaml.Media;using Windows.UI.Xaml.Navigation;// “空白頁”項目範本在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介紹namespace TestData{ /// <summary> /// 可用於自身或導航至 Frame 內部的空白頁。 /// </summary> public sealed partial class MainPage : Page { Person myPerson = new Person(){ Name = "why" , Age = 20 }; public MainPage() { this.InitializeComponent(); } /// <summary> /// 在此頁將要在 Frame 中顯示時進行調用。 /// </summary> /// <param name="e">描述如何訪問此頁的事件數目據。Parameter /// 屬性通常用於配置頁。</param> protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { text1.DataContext = myPerson; } } private void Button_Click_1(object sender, RoutedEventArgs e) { MessageDialog myDialog = new MessageDialog(myPerson.Name); myDialog.ShowAsync(); } private void Button_Click_2(object sender, RoutedEventArgs e) { myPerson.Name = DateTime.Now.Millisecond.ToString(); } }}
然後在xaml版面設定textbox的資料繫結,將其綁定到資料來源的Name屬性上(前面設定的資料來源):
完整的xaml代碼如下:
<Page x:Class="TestData.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:TestData" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <TextBox x:Name="text1" HorizontalAlignment="Center" Margin="0,0,0,0" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Center"/> <Button Content="讀取" HorizontalAlignment="Center" Margin="0,-100,0,0" VerticalAlignment="Center" Click="Button_Click_1"/> <Button Content="改變" HorizontalAlignment="Center" Margin="0,100,0,0" VerticalAlignment="Center" Click="Button_Click_2"/> </Grid></Page>
運行項目,發現顯示的是why,但是點擊修改之後textbox中的值並沒有改變,因為text不知道其中發生了變化。
那麼如何在Name發生變化的時候立即得知?
我們需要修改Person這個類。
在資料繫結中,建議大家實現一個INotifyPropertyChanged介面。
它只有一個成員,就是PropertyChanged事件。
將set稍作修改即可。完整的Person.cs檔案如下:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;namespace TestData{ class Person : INotifyPropertyChanged { private string _name; public string Name { get { return _name; } set { _name = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } private int _age; public int Age { get { return _age; } set { _age = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Age")); } } } public event PropertyChangedEventHandler PropertyChanged; }}
此時再運行,點擊修改的時候TextBox裡面就會跟著變化了。
順便說一下,繫結模式一共分三種,
- OneTime:一次綁定
- OneWay:單向綁定
- TwoWay:雙向繫結
子控制項會預設繼承父控制項的綁定資料,這就是資料內容的概念。比如上面說到的綁定資料來源,也可以寫成:this.DataContext = myPerson;