Different Ways to Bind WPF View And View Model

Datetime:2016-08-23 03:55:52          Topic: WPF           Share

How to bind View and View model in WPF or how to set DataContext of View? In this article I will discuss about the different ways to bind the View and View Model in WPF. In one of my article I have discussed about the MVVM pattern in the WPF and its various components (i.e. View, View Model and Model). If you want to learn about the data binding in WPF you can learn here . This article I have developed using C# language.

There are two ways in which we can bind View and View Model.

  1. Binding using View First Approach
  2. Binding using ViewModel First Approach

View First Approach

There are two ways by which we can bind the View and View model in View First approach.

  1. The First is using the Code Behind. Suppose I have a ViewModel which is getting all the process of the system, as shown in the below code.
        public class TaskViewModel
        {        
            public TaskViewModel()
            {
                AllProcess = new ObservableCollection<Process>(Process.GetProcesses());                      
            }      
     
            public ObservableCollection<Process> AllProcess { get; set; }
        }
    
    Please note that I have not used any Model here. In the above case there is no model as I am getting all the process in the View Model only. The view for this project is as shown below code.
    <Window x:Class="CollectioViewSource.MainWindow"
            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"
            xmlns:local="clr-namespace:CollectioViewSource"
            xmlns:system="clr-namespace:System.Diagnostics;assembly=System"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <DataTemplate DataType="{x:Type system:Process}">
                <Border BorderThickness="1" BorderBrush="Black" Width="200">
                    <StackPanel>
                        <TextBlock Text="{Binding ProcessName}"></TextBlock>
                        <TextBlock Text="{Binding Id}"></TextBlock>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </Window.Resources>
        <Grid>
            <ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Column="0" Grid.Row="1">
              <ListBox ItemsSource="{Binding AllProcess}" >              
              </ListBox>
            </ScrollViewer>
        </Grid>
    </Window>
    
    Now to bind the ViewModel(TaskViewModel in our case) and View(MainWindow.xaml) we have to write the below code. This is the code present in the MainWindow() constructor.
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = new TaskViewModel();
            }
    
    The above code is setting the DataContext of the MainWindow as instance of the TaskViewModel. The ListBox is bound to the AllProcess property. This property should be present in the DataContext instance which is TaskViewModel in our case.

    Now since the AllProcess is collection of type Process(System.Diagnostics). I have defined a data template for Process type .Once the xaml parser encounters the Listbox it starts looking in the Resource Dictionaries to check for template of the Process type. If it finds it binds to it and we can see the result as shown in the last figure of article.

  2. The other approach to bind the View and Viewmodel in View First Approach is in the xaml itself as shown in the figure below.

    View View-Model Binding

    I am setting the datacontext in the .xaml of the View itself. To set the datacontext in this way the ViewModel class need to have a default constructor. This is the preferable way of we not expecting any parameters for the constructor of View Model.

VIew Model First Approach

The next approach is to use initialize the view model first. First lets check the MainWindow.xaml code

View Model First Approach

The code behind of the MainWindow.xaml is nothing apart from the InitializeComponent() method. The dataContext of the MainWindow.xaml is MainWindowViewModel.cs. Its code is as shown below. It has a property of type CustomerListViewModel named CurrentViewModel.

    public class MainWindowViewModel
    {
        public CustomerListViewModel CurrentViewModel { get; set; }
 
        public MainWindowViewModel()
        {
            CurrentViewModel = new CustomerListViewModel();
        }
    }
 
    public class CustomerListViewModel
    {
        private string firstSearchText;
        private string secondSearchText;
        public CustomerListViewModel()
        {
            AllProcess = new ObservableCollection<Process>(Process.GetProcesses());
        }      
        public ObservableCollection<Process> AllProcess { get; set; }
    }

This is the only code for View Model FIrst Approach. And it is quite self explanatory. I have created a ContentControl in the MainWindow.xaml. The property to which it is bound is CurrentViewModel which is of type CustomerListViewModel in MainWindowViewModel. I have created a DataTemplate for the CustomerListViewModel data type. The DataTemplate contains a UserControl named CustomerListVIew. The code CustomerListView is as shown below

<UserControl x:Class="CollectioViewSource.CustomerListView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:system="clr-namespace:System.Diagnostics;assembly=System"
            xmlns:local="clr-namespace:CollectioViewSource"
            mc:Ignorable="d"
            d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type system:Process}">
            <Border BorderThickness="1" BorderBrush="Black" Width="200">
                <StackPanel>
                    <TextBlock Text="{Binding ProcessName}"></TextBlock>
                    <TextBlock Text="{Binding Id}"></TextBlock>
                </StackPanel>
            </Border>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Column="0" Grid.Row="1">
            <ListBox ItemsSource="{Binding AllProcess}" >
            </ListBox>
        </ScrollViewer>
    </Grid>
</UserControl>

This is the control which is finally rendered in the View.

In all the three cases, the view which we get is as shown below. The only thing that is different is approach.

View

Conclusion:

For any WPF application using MVVM approach we should be aware of the ways to bind the VIew and View Model. In this article I have shown the different ways to bind the View and View Model.





About List