Wednesday 29 July 2015

Create simple WPF MVVM application


Creating simple WPF MVVM application

I am taking example of Address book application.

To create MVVM application, as a pre-requisite lets first have WPF application ready.

So the new WPF application ‘SImpletWPFApplication” is created and it is displayed in solution explorer as shown below.




Create View, Model and ViewModel folders in WPF project.

Let’s start with Model, here I am adding AddressBook Model which inherits INotifyPropertyChanged Interface.

Also I have added required implementation for INotifyPropertyChanged Interface in AddressBook Model. You can see complete AddressBookModel code below.



Next, create properties. Properties like Name, PhoneNumber and Email Property are created. You can see complete code below.

    public class AddressBookModel:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        private string name = string.Empty;
        private string phoneNumber = string.Empty;
        private string email = string.Empty;

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }

        public string PhoneNumber
        {
            get
            {
                return phoneNumber;
            }
            set
            {
                phoneNumber = value;
                OnPropertyChanged("PhoneNumber");
            }
        }

        public string Email
        {
            get
            {
                return email;
            }
            set
            {
                email = value;
                OnPropertyChanged("Email");
            }
        } 

    }

One more class is created called ViewModelBase. In that some common functionality is implemented this can be reused later. This class inherits INotifyPropertyChanged interface.
Further I have created ViewModel inside which AddressBookViewModel is created.

public class ViewModelBase:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propName)
        {
            if(PropertyChanged!=null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }
    }


ViewModelBase class is inherited in AddressBookViewModel class to reuse PropertyChanged functionality notification
Note: Same ViewModelBase class can be used in Model Class.

Properties are created in ViewModelBase class to bind view UI elements.
Next create new Window in view folder. Name it as AddressBookView. In this view some simple design is created.

<Window x:Class="SimpleWPFApplicaiton.View.AddressBookView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Address Book" Height="300" Width="300">
    <Grid Background="AliceBlue">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100*"/>
            <ColumnDefinition Width="100*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40*"/>
        </Grid.RowDefinitions>
      
        <TextBlock Grid.Column="0" Grid.Row="0">Name</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="1">Email</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="2">Phone Number</TextBlock>
       
        <TextBox Grid.Column="1" Grid.Row="0" Margin="5"></TextBox>
        <TextBox Grid.Column="1" Grid.Row="1" Margin="5"></TextBox>
        <TextBox Grid.Column="1" Grid.Row="2" Margin="5"></TextBox>
       
        <Button Grid.Column="1" Grid.Row="3" Margin="5" Width="100" HorizontalAlignment="Right">Add</Button>
      
    </Grid>
</Window>


Here I am using MVVM approach, to do loosely couple binding for events . Create custom command class. Let’s name it as RelayCommand and place this in new folder called Helpers. This class inherits ICommand interface to get ICommand feature implementation.
Complete code of RelayCommand as follows.


public class RelayCommand:ICommand
    {
        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {

        }

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }
    }


Again go to AddressBookViewModel class. You can write commands. In my sample application I have created AddCommand.


public class AddressBookViewModel : ViewModelBase
    {
        private RelayCommand addCommand;

        private string name = string.Empty;
        private string phoneNumber = string.Empty;
        private string email = string.Empty;

        public ICommand AddCommand
        {
            get
            {
                if (addCommand == null)
                {
                    addCommand = new RelayCommand(Add);
                }
                return addCommand;
            }
        }

        private void Add(object obj)
        {
            //Logic here to add records
        }

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }

        public string PhoneNumber
        {
            get
            {
                return phoneNumber;
            }
            set
            {
                phoneNumber = value;
                OnPropertyChanged("PhoneNumber");
            }
        }

        public string Email
        {
            get
            {
                return email;
            }
            set
            {
                email = value;
                OnPropertyChanged("Email");
            }
        }

    }



Further we need to bind this ModelView to View. 
Using below line we will get reference of view model
xmlns:viewModel="clr-namespace:SimpleWPFApplicaiton.ViewModel"



Next, create key to get access to above view model. By this key you can bind to UI elements.
In below code you can see few changes related to binding.


<Window x:Class="SimpleWPFApplicaiton.View.AddressBookView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:SimpleWPFApplicaiton.ViewModel"
        Title="Address Book" Height="300" Width="300">
    <Window.Resources>
        <viewModel:AddressBookViewModel x:Key="AddressBookVM"/>
    </Window.Resources>
    <Grid Background="AliceBlue" DataContext="{StaticResource AddressBookVM}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100*"/>
            <ColumnDefinition Width="100*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40*"/>
        </Grid.RowDefinitions>
      
        <TextBlock Grid.Column="0" Grid.Row="0">Name</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="1">Email</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="2">Phone Number</TextBlock>
       
        <TextBox Grid.Column="1" Grid.Row="0" Margin="5" Text="{Binding Name}" ></TextBox>
        <TextBox Grid.Column="1" Grid.Row="1" Margin="5" Text="{Binding Email}" ></TextBox>
        <TextBox Grid.Column="1" Grid.Row="2" Margin="5" Text="{Binding PhoneNumber}" ></TextBox>
       
        <Button Grid.Column="1" Grid.Row="3" Margin="5" Width="100" HorizontalAlignment="Right" Command="{Binding AddCommand}" >Add</Button>
      
    </Grid>
</Window>

Now inside ViewModel, in Add method you can implement logic which you required.
Before running the application set start of window to AddressBookView.
Hope this will help you...:)

Comments and suggestions are welcome J