silverlight數據綁定模式TwoWay,OneWay,OneTime的研究

asp.net開發中,數據綁定是一個很簡單的概念,控件與數據綁定後,控件可以自動把數據按一定的形式顯示出來。(當然控件上的值改變後,可以通過提交頁面表單,同時後臺服務端代碼接收新值更新數據)

silverlight中利用控件顯示數據這一基本功能當然還保留,只不過因爲silverlight應用不需要刷新(也不存在提交表單),所以當控件屬性或數據源變化後,在如何相互影響這一塊的處理上有所不同。

引用一段silverlight 3 sdk官方的解釋:

...

Silverlight 支持以下三種類型的綁定:

創建 OneTime 綁定時,該綁定使用源數據更新目標。

創建 OneWay 綁定時以及每當源數據發生變化時,該綁定使用源數據更新目標。這是默認模式。

當目標和源有一個發生變化時,TwoWay 綁定既更新目標也更新源。或者,您可以禁用自動源更新,只在您選擇的時間對源進行更新。

爲了能夠發生自動目標更新,源對象必須實現 INotifyPropertyChanged 接口,如下一部分所述。

...


簡單的說:

OneTime模式下:控件與數據綁定後,能自動顯示數據,一旦顯示完成後,這二者就沒有任何關聯了。(即自動解除綁定)
OneWay模式下:控件與數據綁定後,除自動顯示數據外,顯示完成後,控件與數據源仍有單向關聯,即如果數據源以後發生了變化,控件上的值也會自動變化.
TwoWay模式下:基本與OneWay相同,但是顯示完成後,控件與數據源的關聯是雙向的,即數據源的變化會影響控件上的值,反過來控件上的任何值變化也會影響數據源本身發生變化。


來看一個簡單的例子: 

<UserControl x:Class="BindingStudy.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">
    
<StackPanel x:Name="LayoutRoot">

        
<Rectangle x:Name="rect" Stroke="Black" HorizontalAlignment="Center" VerticalAlignment="Center" Width="{Binding Value, ElementName=silderSelf, Mode=OneTime}"  

Height
="80" ></Rectangle>

        
<Slider Width="200" Minimum="1" Maximum="200" Value="20" x:Name="silderSelf" Margin="0,10,0,0"></Slider>

        
<StackPanel x:Name="sp_Mode" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10,0,0">
            
<RadioButton Content="OneTime" x:Name="rboMode_OneTime" GroupName="bindMode" IsChecked="True" Checked="rboMode_OneTime_Checked"></RadioButton>
            
<RadioButton Content="OneWay" x:Name="rboMode_OneWay" GroupName="bindMode" Margin="10,0,0,0" Checked="rboMode_OneWay_Checked" ></RadioButton>
            
<RadioButton Content="TwoWay" x:Name="rboMode_TwoWay" GroupName="bindMode" Margin="10,0,0,0" Checked="rboMode_TwoWay_Checked" ></RadioButton>
        
</StackPanel>
        
        
<StackPanel x:Name="sp_Button" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10,0,0">
            
<Button x:Name="btnWidthAdd" Content="矩形寬度+5px" Click="btnWidthAdd_Click"></Button>
            
<Button x:Name="btnWidthSub" Content="矩形寬度-5px" Margin="10,0,0,0" Click="btnWidthSub_Click"></Button>
        
</StackPanel>
    
</StackPanel>
</UserControl>


解釋一下:

最上面是一個矩形rect,下面是一個滑塊拖動條silderSelf,其它的先不管,矩形的Width屬性注意一下:

Width="{Binding Value, ElementName=silderSelf, Mode=OneTime}"

這裏將矩形的寬度與滑塊的Value值做了綁定(即矩形的寬度即爲滑動條的值),模式爲OneTime(即綁定完成後,二者再無任何關聯)

tips:上面提到的綁定語法不用死記硬背,在Blend裏用圖形界面即可設置

選中矩形對象,點擊屬性面板Width右邊的小黃點,彈出菜單中選擇"Data Binding..."

設置綁定

運行效果: 

 

先不用急着關注其它東西,我們注意到矩形的寬度自動變成20了,即silder的value初始值,然後我們拖動滑塊試下,矩形的寬度沒有變化!也就映證了OneTime模式下,一旦綁定完成(數據顯示結束),控件與數據源就再無任何瓜葛,大家各走各的路,各過各的橋。

爲了測試另外二種模式,我在後臺加了一些代碼 :

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace BindingStudy
{
    
public partial class MainPage : UserControl
    
{
        
public MainPage()
        
{
            InitializeComponent();
        }


        
private void rboMode_OneTime_Checked(object sender, RoutedEventArgs e)
        
{
            
if (rect != null)
            
{
                Binding bindwidth 
= new Binding("Value");
                bindwidth.Mode 
= BindingMode.OneTime;
                
this.rect.SetBinding(UserControl.WidthProperty, bindwidth);
                
this.rect.DataContext = silderSelf;
            }

        }


        
private void rboMode_OneWay_Checked(object sender, RoutedEventArgs e)
        
{
            
if (rect != null)
            
{
                Binding bindwidth 
= new Binding("Value");
                bindwidth.Mode 
= BindingMode.OneWay;
                
this.rect.SetBinding(UserControl.WidthProperty, bindwidth);
                
this.rect.DataContext = silderSelf;
            }

        }


        
private void rboMode_TwoWay_Checked(object sender, RoutedEventArgs e)
        
{
            
if (rect != null)
            
{
                Binding bindwidth 
= new Binding("Value");
                bindwidth.Mode 
= BindingMode.TwoWay;
                
this.rect.SetBinding(UserControl.WidthProperty, bindwidth);
                
this.rect.DataContext = silderSelf;
            }

        }


       
        
private void btnWidthAdd_Click(object sender, System.Windows.RoutedEventArgs e)
        
{
            
if (rect != null
            
{
                rect.Width 
+= 5;
            }

        }


        
private void btnWidthSub_Click(object sender, System.Windows.RoutedEventArgs e)
        
{
            
if (rect != null)
            
{
                rect.Width 
-= 5;
            }

        }

    }

}


代碼不復雜,基本功能就是讓綁定模式可以自由切換,相信大家一看就明白

這回我們來測試一下OneWay模式,運行後選擇OneWay模式,然後再手動拖動滑塊,會發現矩形的寬度隨着滑塊的值不斷變化,即OneWay模式下,數據源的變化會自動反應在綁定的目標控件上,繼續,我們點擊最下面的二個按鈕,改變矩形的寬度,發現滑塊不會自己移動,這說明了OneWay模式下控件的屬性變化,不會反過來影響數據源本身。


最後切換到TwoWay模式,與OneWay模式的不同之外在於,如果我們點擊最下面的按鈕,改變矩形的寬度,會發現滑塊自己移動了,移動後的值即爲矩形的寬度,結論:TwoWay模式下,控件與數據源任何一方的變化都會影響對另一方。(個人感覺這個功能很NB,如果我們自己實現的話,不知道要寫多少行代碼!)


當然,實際開發中,我們的數據源通常不會是某一個現成控件的屬性,多半是xml/數據庫等對應的實體類,這裏要注意的是,如果控件與自定義類綁定,自定義類必須實現INotifyPropertyChanged接口,參考下面的代碼:

 

 public class Test : INotifyPropertyChanged
    
{
        
public event PropertyChangedEventHandler PropertyChanged;

        
private double _width;

        
public double Width
        
{
            
set
            
{
                _width 
= value;
                
if (PropertyChanged != null
                
{
                    PropertyChanged(
thisnew PropertyChangedEventArgs("Width"));
                }

            }


            
get
            
{
                
return _width;
            }

        }

    }

 

綁定示例代碼:

Binding bindwidth = new Binding("Width");
bindwidth.Mode 
= BindingMode.OneTime;
this.rect.SetBinding(UserControl.WidthProperty, bindwidth);
Test t 
= new Test();
t.Width
=100;
this.rect.DataContext = t; 

 

轉載請註明來自菩提樹下的楊過

原文地址:http://www.cnblogs.com/yjmyzz/archive/2009/11/09/1599058.html 

最後給出文中源碼下載:http://files.cnblogs.com/yjmyzz/BindingStudy.rar

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