WPF學習07:MVVM 預備知識之數據綁定

    MVVM是一種模式,而WPF的數據綁定機制是一種WPF內建的功能集,二者是不相關的。html

    可是,藉助WPF各類內建功能集,如數據綁定、命令、數據模板,咱們能夠高效的在WPF上實現MVVM。所以,咱們須要對各類MVVM相關的WPF內建功能集進行了解,才能在紮實的基礎上對MVVM進行學習與實踐。學習

    本文是WPF學習03:Element Binding的後續,將說明實現數據綁定的三個重點:DataContext INotifyPropertyChanged IValueConverterthis

 

MVVM簡介

    MVVM將User Interface切成了3個部分,View、Model、View Model.spa

    三個部分區分以下:3d

    View:界面代碼,並完成數據可視化。code

    Model:一系列咱們與業務層交互的類。htm

    View Model:1.將Model中須要顯示的部分,轉化爲對View友好的數據。    2.管理View與View之間的交互。   對象

   image

    依賴關係如上圖所示,V依賴於VM,反之不該該成立,VM依賴於M,反之亦不該成立。blog

    在完成了對數據綁定、命令、數據模板的理解後,咱們再從新回來解釋MVVM。接口


 

DataContext

    在WPF學習03:Element Binding中,咱們只研究瞭如何在控件間實現數據綁定,在不指定ElementName時,Binding會在Source與RelativeSource也沒有設置的狀況下,一級一級的尋找DataContext,直到找到。

    例子:

    image

<StackPanel HorizontalAlignment="Center" TextBlock.Foreground="#019AFF" DataContext="{x:Static Colors.White}">
    <!--指定Path,綁定對象的某個屬性-->
    <TextBlock Text="{Binding Path=R}"></TextBlock>
    <TextBlock Text="{Binding Path=G}"></TextBlock>
    <TextBlock Text="{Binding Path=B}"></TextBlock>
    <!--不指定Path,綁定整個對象-->
    <TextBlock Text="{Binding}"></TextBlock>
</StackPanel>

     比較經常使用的狀況下,咱們將DataContext設置在最頂層元素,通常狀況下爲Window。

     咱們能夠在後臺代碼中配置DataContext:

public class Person
{
    private Int32 _age;
        
    public Int32 Age 
    {
        get { return _age; }
        set { _age = value; }
    }

    private String _name;

    public String Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    person = new Person() { Name = "Kenny", Age = 30 };
    this.DataContext = person;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    person.Name = "John Locke";
    person.Age = 40;
}

    XAML作的改動:

<StackPanel HorizontalAlignment="Center" TextBlock.Foreground="#019AFF">
    <TextBlock Text="{Binding Path=Name}"></TextBlock>
    <TextBlock Text="{Binding Path=Age}"></TextBlock>
    <Button Click="Button_Click">Click me</Button>
</StackPanel>

    效果以下:

    image

     咱們能夠看到的確顯示了指望值,可是若是點擊按鍵的話,是看不到任何變化的,接下來即解釋緣由與解決方法。


 

INotifyPropertyChanged

    WPF內建的數據綁定機制中,Dependency Property不需額外作任何配置,便可在通常狀況下創建數據綁定關係。WPF自建控件的各種屬性都是依賴屬性經傳統的.Net屬性包裝而成。

    若是咱們但願將數據綁定的源設爲咱們本身定義的對象的屬性,且該屬性不爲依賴屬性,那麼就只有靠實現INotifyPropertyChanged接口,並在相應的屬性改變時調用PropertyChanged事件以通知目標元素。

    咱們將以前的後臺代碼作以下的改動:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private Int32 _age;    
    public Int32 Age 
    {
        get { return _age; }
        set { 
            _age = value;
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Age"));
        }
    }

    private String _name;
    public String Name
    {
        get { return _name; }
        set {
            _name = value;
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
        }
    }

}

    效果以下:

    image

   


 

IValueConverter

    某些特殊的時候,源屬性與目標屬性是沒法鏈接,須要進行轉換,這時,就須要用到ValueConverter.直接給個例子:

    數據綁定實現根據年齡不一樣,文字顯示同顏色,效果:

    imageimage

    XAML代碼:

<TextBlock Text="{Binding Path=Name}"></TextBlock>
<TextBlock Name="AgeTextBlock" Text="{Binding Path=Age}">
<TextBlock.Foreground>
        <Binding Path="Age">
            <Binding.Converter>
                <local:TextBlockColorValueConverter></local:TextBlockColorValueConverter>
            </Binding.Converter>
        </Binding>
</TextBlock.Foreground>
</TextBlock>
    後臺代碼:
[ValueConversion(typeof(Boolean), typeof(Int32))]
public class TextBlockColorValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if ((int)value < 18)
            return new SolidColorBrush(Colors.Violet);
        else
            return new SolidColorBrush(Colors.Red);
    }

    //這裏用不上數據從目標返回源,故返回null
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

 

數據綁定的後臺代碼實現

     以前的數據綁定都是用XAML實現的,在此給出後臺代碼實現數據綁定的方法,實現剛纔的例子:

     首先給兩個控件標個Name,並去掉以前的全部綁定相關代碼:

<TextBlock Name="NameTextBlock"></TextBlock>
<TextBlock Name="AgeTextBlock"></TextBlock>

      後臺代碼:

var bind = new Binding("Name")
{
    Source = person,
};
NameTextBlock.SetBinding(TextBlock.TextProperty, bind);
bind = new Binding("Age")
{
    Source = person,
};
AgeTextBlock.SetBinding(TextBlock.TextProperty, bind);
bind = new Binding("Age")
{
    Source = person,
    Converter = new TextBlockColorValueConverter()
};
AgeTextBlock.SetBinding(TextBlock.ForegroundProperty, bind);
    效果與以前一致。
相關文章
相關標籤/搜索