在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的綁定
可以在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上的,詳細介紹在下一篇文章中再做說明。
工程源代碼上傳在GitHub上了:https://github.com/feipeng8848/WPF-Demo
參考:https://rachel53461.wordpress.com/2012/07/14/what-is-this-datacontext-you-speak-of/