[WPF][Silverlight] Binding in WPF and Silverlight – (一)使用C#

  • 5501
  • 0
  • C#
  • 2013-07-14

WPF和Silverlight從2.0版之後就一直針對Data Binding的部份不停的在做改善,現在甚至可以透過Visual Studio 2010或Blend 4.0在設計模式裡透過幾下滑鼠的點擊就可以完成Binding的設定。
所謂的Binding呢,中文的翻譯是「繫結」,有玩線上遊戲的朋友應該也都會聽過一個名詞叫「綁定」,其實指的都是同一個英文單字—Binding,意思就是把兩件東西連結在一起。

WPF和Silverlight從2.0版之後就一直針對Data Binding的部份不停的在做改善,現在甚至可以透過Visual Studio 2010或Blend 4.0在設計模式裡透過幾下滑鼠的點擊就可以完成Binding的設定。
所謂的Binding呢,中文的翻譯是「繫結」,有玩線上遊戲的朋友應該也都會聽過一個名詞叫「綁定」,其實指的都是同一個英文單字—Binding,意思就是把兩件東西連結在一起

而Binding的組成包含了以下幾樣東西:

  • Source:要繫結的對象(也可以看作是資料的來源),可以是一個控制項,也可以是一個Class的Instance,更可以是一個Class的集合(Collection)
  • Path:要繫結到的對象的屬性(Property)
  • Target Property:被繫結的目標的屬性(必需為Dependency Property才行)
  • Binding本身:Binding本身也是一個物件,在裡面可以決定繫結的方向(如單向、雙向、一次性繫結等等)
  • ValueConverter:轉換器,用來處理不同型別Property之間的值轉換

用比較淺顯易懂的方式來描述Binding的話,就如下圖:
DataBinding

如果有仔細看上圖的話,應該會發現:咦?INotifyPropertyChanged這玩意兒是哪來的??其實它是.Net裡面一個看來簡單但是功能強大的介面,透過它來實作雙向的繫結就會易如反掌,之後會跟各位分享這個介面在資料繫結中的使用。 Ok,先讓我們來重溫一下沒有Binding的世界是怎麼寫程式的吧。
我們先建立一個Silverlight專案,在畫面上放一個Calendar和一個TextBlock,然後當Calendar的SelectedDate改變的時候,就把日期顯示到TextBlock裡,要做到這樣的功能,Xaml和cs檔如下:

MainPage.xaml
<UserControlx:Class="SilverlightDataBinding.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"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
mc:Ignorable="d"
d:DesignWidth="800"d:DesignHeight="600"
Width="Auto"Height="Auto">
    <Gridx:Name="LayoutRoot"Background="Transparent">
        <StackPanelHorizontalAlignment="Center"VerticalAlignment="Center">
            <sdk:CalendarHorizontalAlignment="Center"Name="calCalendar"Width="Auto" SelectedDatesChanged="calCalendar_SelectedDatesChanged"/>
            <TextBoxHeight="23"HorizontalAlignment="Stretch"Name="txtDate"Width="Auto"/>
        </StackPanel>
    </Grid>
</UserControl>
MainPage.cs
using System.Windows.Controls;
 
namespace SilverlightDataBinding
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void calCalendar_SelectedDatesChanged( object sender , SelectionChangedEventArgs e )
        {
            this.txtDate.Text = calCalendar.SelectedDate.ToString();
        }
    }
}

 

很簡單對吧!!但是用了Binding之後,更簡單!!而且之後要介紹的方式會越來越簡單,請耐心看下去。

前面有說到Binding的幾個組成要素,在上面的例子中,Source就是calCalendarPath就是SelectedDateTarget當然就是txtDate的TextProperty屬性囉,再來我們就直接在cs檔裡面寫Binding吧!!首先我們把calCalendar的SelectedDatesChanged EvnetListener拿掉。

MainPage.xaml
<UserControl x:Class="SilverlightDataBinding.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"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    mc:Ignorable="d"
    d:DesignWidth="800" d:DesignHeight="600"
    Width="Auto" Height="Auto">
 
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <sdk:Calendar HorizontalAlignment="Center" Name="calCalendar" Width="Auto" />
            <TextBox Height="23" HorizontalAlignment="Stretch" Name="txtDate" Width="Auto" />
        </StackPanel>
    </Grid>
</UserControl>

MainPage.cs改為如下:

MainPage.cs
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;
 
namespace SilverlightDataBinding
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
 
            //宣告Binding物件 
            Binding binding = new Binding();
            
            //設定Source Object
            binding.Source = this.calCalendar;
 
            //指定Path為Source的哪個Property
            binding.Path = new PropertyPath( "SelectedDate" );
 
            //建資料繫結
            txtDate.SetBinding( TextBox.TextProperty , binding );
        }
    }
}

 

再執行看看,是不是結果完全一樣呢?但是,看到這邊,你可能會說,我原來只要一行就搞定了,為什麼改用Binding,卻變成要四行!?難不成這是騙小孩嗎!?其實也可以寫成一行啦:

BindingOperations.SetBinding( txtDate , TextBox.TextProperty , new Binding { Source = this.calCalendar , Path = new PropertyPath( "SelectedDate" ) } );

 

或是寫成

txtDate.SetBinding( TextBox.TextProperty , new Binding { Source = this.calCalendar , Path = new PropertyPath( "SelectedDate" ) } );

 

都是可以的。

那問題就又來啦,之前用EventHandler的作法,還可以藉由把EventHandler拿掉來停止值的更新,用Binding的話也行嗎?就算是「拾取後綁定」也總應該可以刪除吧!?當然可以把Binding做清除的動作!!
清除Binding的方式很多,在Silverlight裡的話,可以使用以下方式:

//1.使用ClearValue方法
txtDate.ClearValue( TextBox.TextProperty );
//2.直接賦與一個新的值
txtDate.Text = string.Empty;

 

如果是WPF呢?那方法更多了:

//1.使用BindingOperations.ClearBinding方法
BindingOperations.ClearBinding( txtDate , TextBox.TextProperty );
//2.使用BindingOperations.ClearAllBinding方法
BindingOperations.ClearAllBindings( txtDate );
//3. 直接賦與一個新的值
txtDate.Text = string.Empty;

 

這次就先到此為止啦,下篇再來講講直接使用XAML來做到Binding。