官术网_书友最值得收藏!

Connecting Views with View Models

In WPF, there are several ways to connect our Views to their data sources. We've all seen examples of the simplest method of a View setting its DataContext property to itself in its code behind:

public partial class MainWindow : Window 
{ 
  public MainWindow() 
  { 
    InitializeComponent(); 
    DataContext = this; 
  } 
} 

However, this should only ever be used for quick demonstrations and never in our real-world applications. If we need to data-bind to properties declared in a View's code behind, let's say for a particular custom UserControl, then we should use RelativeSource bindings instead. We'll find out more about this in Chapter 4, Becoming Proficient with Data Binding, but for now, let's continue looking at the alternative ways to connect the Views with their data sources.

The next simplest method utilizes the data templating Model that is built into the WPF Framework. This topic will also be covered in much more detail in Chapter 4, Becoming Proficient with Data Binding, but, in short, a DataTemplate is used to inform the WPF Framework how we want it to render data objects of a particular type. The simple example shows how we could define the visual output of our User objects:

<DataTemplate DataType="{x:Type DataModels:User}"> 
  <TextBlock Text="{Binding Name}" /> 
</DataTemplate> 

In this example, the DataType property specifies which type of object this relates to and therefore, which properties the containing XAML bindings have access to. Keeping it simple for now, we just output the name of each User in this DataTemplate. When we data-bind one or more User objects to a UI control that is within the scope of this DataTemplate, they will each be rendered by the WPF Framework as a TextBlock that specifies their name.

When the rendering engine of the WPF Framework comes across a custom data object, it looks for a DataTemplate that has been declared for its type and, if it finds one, it renders the object according to the XAML contained within the relevant template. This means that we can create a DataTemplate for our View Model classes that simply specifies their related View classes as the rendering output:

<DataTemplate DataType="{x:Type ViewModels:UsersViewModel}"> 
  <Views:UsersView /> 
</DataTemplate> 

In this example, we have specified that when the WPF Framework sees an instance of our UserViewModel class, it should render it as one of our UserView classes. At this point, it will set our View Model instance to the DataContext property of the related View implicitly. The only downside to this method is minimal, and is that we have to add a new DataTemplate to our App.xaml file for each of our View-View Model pairs.

This method of connection works View Model first, where we supply the View Model instance and the WPF Framework takes care of the rest. In these cases, we typically use a ContentControl that has its Content property data bound to a ViewModel property, which the application View Models are set to. The WPF Framework notes the type of the View Model that is set and renders it according to its specified DataTemplate:

private BaseViewModel viewModel; 
 
public BaseViewModel ViewModel 
{ 
  get { return viewModel; } 
  set { viewModel = value; NotifyPropertyChanged(); } 
} 
    
... 
    
ViewModel = new UserViewModel(); 
    
...
     
<ContentControl Content="{Binding ViewModel}" /> 

This is the preferred version of View to View Model connections for many, as the WPF Framework is left to take care of most of the details. However, there is another way to construct these connections that adds a layer of abstraction to the process.

主站蜘蛛池模板: 北碚区| 章丘市| 南川市| 南岸区| 安图县| 兰西县| 广宁县| 太仆寺旗| 东至县| 永济市| 陆丰市| 阳原县| 夏津县| 容城县| 惠水县| 韩城市| 游戏| 武鸣县| 蒙阴县| 新邵县| 革吉县| 威海市| 师宗县| 阆中市| 黄浦区| 肃宁县| 金湖县| 朝阳县| 濮阳市| 静安区| 沛县| 平潭县| 扶沟县| 周至县| 靖安县| 永寿县| 沾化县| 察哈| 柳江县| 盐源县| 鄂托克前旗|