WPF--DataContext

在WPF中,應用程序有兩層:UI層和Data層。這裏新建一個項目說明哪些是UI層,哪些是數據層。

UI層很明顯,就是用戶看到的界面。但是數據層並不是下圖所示:

上圖中是UI層view的後臺代碼。當然,你可以使用事件的方式把所有的業務邏輯代碼寫到這裏,但是我們採用MVVM的時候業務邏輯是與這裏解耦的,數據層是DataContext,此時並沒有指定。
接下來我們新建個目錄,然後添加個類文件:

然後指定VM類爲DataContext:

此時我們纔算爲MVVM模式的wpf應用程序創建了數據層,也就是MainViewModel類。

默認,應用程序的數據層(DataContext)是null,我們可以使用DataContext屬性對其進行設置。
除非另行指定,否則所有UI對象都將從其父對象繼承其DataContext
實際上DataContext纔算是我們的實際應用程序(業務邏輯),他通常由ViewModels和Models組成。
UI對象(如按鈕,標籤,DataGrids甚至Windows)實際作用是允許用戶輕鬆與DataContext交互。
當你寫<Label Name="myLabel" Content="{Binding Path=Name}" />你是綁定到myLabel.DataContext.Name,而不是myLabel.Name。

<!-- 注意此時我已經在初始化代碼中設置DataContext 爲 ClassA,DataContext = new ClassA  -->
<Window x:Name="MyWindow"> 
 
    <!-- DataContext 沒有被指定,所以繼承自父類
         的 DataContext,也就是 ClassA -->
    <StackPanel> 
 
        <!-- DataContext 繼承自父類,也就是 
             ClassA, 所以這裏會顯示 ClassA.Name -->
        <Label Content="{Binding Name}" />
 
         <!-- DataContext 仍然是ClassA, 但是我們通過binding設置爲ClassA.ClassB-->
        <StackPanel DataContext="{Binding ClassB}">
 
            <!-- DataContext 繼承自父類,也就是ClassB,所以這裏會顯示 ClassB.Name -->
            <Label Content="{Binding Name}" />
 
            <!-- DataContext i仍然是 ClassB, 但是我們binding 到了Window's DataContext.Name, 也就是 ClassA.Name -->
            <Label Content="{Binding 
                       ElementName=MyWindow, 
                       Path=DataContext.Name}" /> 
        </StackPanel>
 
        <!-- We've left the StackPanel with its DataContext 
             bound to ClassB, so this Label's DataContext 
             is ClassA (inherited from parent StackPanel), 
             and we are binding to ClassA.ClassB.Name -->
        <Label Content="{Binding ClassB.Name}" />
    </StackPanel>
</Window>

所有基本綁定都在UI對象的數據層(DataContext)中尋找它們的值。
綜上所述,WPF應用程序具有兩層:UI層和數據層。應用程序的數據層以null開頭,可以使用DataContext屬性設置。未設置DataContext的UI對象將從其父對象繼承其數據層。綁定用於在數據層中查找值,並在UI層中顯示它們。
使用MVVM設計模式時,數據層是您的應用程序,而UI層只是提供了一種用戶友好的方式來訪問數據層。

datacontext的綁定

pis:(直接在XAML上指定根datacontext貌似不行,必須通過代碼或者引入資源(此方式還未實踐)的方式來指定,後續子元素的datacontext可以通過binding來指定則是可行的,它們的根都是之前設定的根datacontext)
可以在view的後臺代碼中手動指定例如在構造函數中:

var cont = new MainViewModle();
DataContext = cont;

 

另外也可以寫到資源中,首先需要寫一個viewmodel類:

public MainViewModel()
{
    plusCommand = new PlusCommand(this);
}

 

然後把vm類放到資源中:

<!--需要指定名稱空間vm:
xmlns:vm="clr-namespace:SimpleCommandDemoApp.ViewModels"-->
<UserControl.Resources>
    <vm:CalculatorViewModel x:Key="calculatorVM" />
</UserControl.Resources>

 

最後就可以在xaml中指定了:

DataContext="{Binding Source={StaticResource calculatorVM}}"

 

WPF使用DataContext將數據層與UI層實現瞭解耦,那麼他們之間是如何交互的?實際上上面已經略有涉獵,那就是Binding,上面實例的ClassA、ClassB的Name就是通過Binding來展示到UI上的,詳細介紹在下一篇文章中再做說明。

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