CRUD Operations in WPF with MVVM Framework


This Tutorial will explain how to implement crud operations in WPF with MVVM Framework.

Open Visual Studio 2012. Go to create new project tab. Select WPF Application.
Add Five folders to the Application.

  • Model
  • View
  • ViewModel
  • Data
  • Helpers
Employee Data

Employee Data

Design the Data Grid in WPF
Create a MainWindow.xaml file inside View folder in your appliction. Add the below code to the file.

<Grid Margin="0,0,0,-1">
        <Grid.RowDefinitions>
            <RowDefinition Height="0.939*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <GroupBox Header="Employee Data" HorizontalAlignment="Center" VerticalAlignment="Center" Height="383" Margin="5,5,5,5">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <ScrollViewer VerticalScrollBarVisibility="Auto" Margin="5,5,5,5">
                    <StackPanel>
                        <StackPanel Orientation="Horizontal" Margin="5,5,5,5">
                            <DataGrid x:Name="dg1" ItemsSource="{Binding Employee}" SelectedItem="{Binding SelectedEmployee}" CanUserAddRows="False"  CanUserDeleteRows="False" SelectionMode="Single" SelectedIndex="{Binding SelectedIndex}" VerticalAlignment="Top" AutoGenerateColumns="False" Margin="5,5,5,5">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="Emp ID" Binding="{Binding Path=ID}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="DOB" Binding="{Binding Path=DOB,StringFormat=d}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="Gender" Binding="{Binding Path=Gender}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="Nationality" Binding="{Binding Path=Nationality}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="Language" Binding="{Binding Path=Language}"></DataGridTextColumn>
                                    <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}"></DataGridTextColumn>
                                </DataGrid.Columns>
                            </DataGrid>
                        </StackPanel>
                    </StackPanel>
                </ScrollViewer>
                <Button Grid.Row="1" Content="Add Employee" Command="{Binding AddUserCommand}" Margin="5" Focusable="False" HorizontalAlignment="Left" MinWidth="200"/>
            </Grid>
        </GroupBox>
    </Grid>

Create a User.cs class inside Model folder in your Application. Write the below code in the file.

class User : INotifyPropertyChanged
{
    private string _id;
    private string _firstName;
    private string _address;
    private string _lastName;
    private string _language;
    private string _dob;
    private string _nationality;
    private string _gender;
    private bool _male;
    private bool _female;
    private bool _hindi;
    private bool _english;
    private bool _french;

    public User()
    {
    }

    public string ID
    {
        get { return _id; }
        set
        {
            _id = value;
            NotifyOfPropertyChange("ID");
        }
    }
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            _firstName = value;
            NotifyOfPropertyChange("FirstName");
        }
    }
    public string LastName
    {
        get { return _lastName; }
        set
        {
            _lastName = value;
            NotifyOfPropertyChange("LastName");
        }
    }
    public string Address
    {
        get { return _address; }
        set
        {
            _address = value;
            NotifyOfPropertyChange("Address");
        }
    }

    public string Language
    {
        get { return _language; }
        set
        {
            _language = string.Empty;
            string Comma = string.Empty;
            if (Hindi)
            {
                _language = "Hindi";
            }
            if (English)
            {
                if (!string.IsNullOrEmpty(_language))
                {
                    Comma = ",";
                }
                _language = _language + Comma + "English";
            }
            if (French)
            {
                if (!string.IsNullOrEmpty(_language))
                {
                    Comma = ",";
                }
                _language = _language + Comma + "French";
            }
            NotifyOfPropertyChange("Language");
        }
    }

    public string DOB
    {
        get { return _dob; }
        set
        {
            _dob = Convert.ToDateTime(value).ToString("MM/dd/yyyy");
            NotifyOfPropertyChange("DOB");
        }
    }

    public string Nationality
    {
        get { return _nationality; }
        set
        {
            _nationality = value;
            NotifyOfPropertyChange("Nationality");
        }
    }

    public bool Male
    {
        get { return _male; }
        set
        {
            _male = value;
            Gender = "Male";
            NotifyOfPropertyChange("Male");
        }
    }

    public bool Female
    {
        get { return _female; }
        set
        {
            _female = value;
            Gender = "Female";
            NotifyOfPropertyChange("Female");
        }
    }
    public string Gender
    {
        get { return _gender; }
        set
        {
            if (Male)
            {
                _gender = "Male";
            }
            if (Female)
            {
                _gender = "Female";
            }

            NotifyOfPropertyChange("Gender");
        }
    }

    public bool Hindi
    {
        get { return _hindi; }
        set
        {
            _hindi = value;
            Language = "Hindi";
            NotifyOfPropertyChange("Hindi");
        }
    }

    public bool English
    {
        get { return _english; }
        set
        {
            _english = value;
            Language = "English";
            NotifyOfPropertyChange("English");
        }
    }

    public bool French
    {
        get { return _french; }
        set
        {
            _french = value;
            Language = "French";
            NotifyOfPropertyChange("French");
        }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyOfPropertyChange(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

Bind this data grid to ViewModelUser. Write the below code to MainWindow.xaml.cs file.

 this.DataContext = new ViewModelUser();

Create a ViewModelUser.cs class inside ViewModel folder in your application. Add the below code to this class file.

  PersonnelBusinessObject personnel;
  ObservableCollection<User> _Employee;
  public ViewModelUser()
    {
       personnel = new PersonnelBusinessObject();
    }
  public ObservableCollection<User> Employee
    {
       get
         {
            _Employee = new ObservableCollection<User>(personnel.GetEmployees());
            return _Employee;
         }
    }

PersonnelBusinessObject Class is used to write business logic. Create a PersonnelBusinessObject.cs in Model folder of your application.

 class PersonnelBusinessObject
    {
        List<User> Employee { get; set; }
        public PersonnelBusinessObject()
        {
            Employee = DatabaseLayer.GetEmployeeFromDatabase();
        }

        public List<User> GetEmployees()
        {
            return Employee = DatabaseLayer.GetEmployeeFromDatabase();
        }
    }

DatabaseLayer class is used to communicate with database. you can write your stored procedure and queries to fetch data from database.
Create a DatabaseLayer.cs class in Data Folder in your application. Write the below code in this class.

 class DatabaseLayer
{
    public static List<User> GetEmployeeFromDatabase()
    {
        try
        {
            DataTable dt = SqlHelper.ExecuteDataTable(AppConstants.getConnectionString(), CommandType.StoredProcedure, "[dbo].[uspGetUser]");
            var Employee = new List<User>();
            foreach (DataRow row in dt.Rows)
            {
                var obj = new User()
                {
                    ID = (string)row["ID"],
                    FirstName = (string)row["FirstName"],
                    LastName = (string)row["LastName"],
                    DOB = (string)row["DOB"],
                    Gender = (string)row["Gender"],
                    Nationality = (string)row["Nationality"],
                    Language = ((string)row["Language"]),
                    Address = (string)row["Address"],
                    Male = (bool)row["Male"],
                    Female = (bool)row["Female"],
                    Hindi = (bool)row["Hindi"],
                    English = (bool)row["English"],
                    French = (bool)row["French"],
                };
                Employee.Add(obj);
            }
            return Employee;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

After building and running the application data will be populate in the Data grid.
Implementing Insert, Update and Delete operations in WPF with MVVM Framework.

Employee Form

Employee Form

Open the MainWindow.xaml file and add the below code just above to the existing code.

<Window.Resources>
        <!-- This converts SelectedItem to a collection, for use in the ItemsControl -->
        <helpers:SelectedItemToItemsSource x:Key="SelectedItemToItemsSource"/>

        <!-- This is the template for the user form, used by the itemsControl below -->
        <DataTemplate x:Key="UserGrid">
            <Border Background="Chocolate" BorderBrush="Black" BorderThickness="1" CornerRadius="5" >
                <Grid Margin="10">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Emp ID" Grid.Row="1" Grid.Column="0"/>
                    <TextBlock Text="First Name" Grid.Row="2" Grid.Column="0"/>
                    <TextBlock Text="Last Name" Grid.Row="3" Grid.Column="0"/>
                    <TextBlock Text="Address" Grid.Row="4" Grid.Column="0"/>
                    <TextBlock Text="Gender" Grid.Row="5" Grid.Column="0"/>
                    <TextBlock Text="Language" Grid.Row="6" Grid.Column="0"/>
                    <TextBlock Text="Nationality" Grid.Row="7" Grid.Column="0"/>
                    <TextBlock Text="DOB" Grid.Row="8" Grid.Column="0"/>
                    <TextBox Text="{Binding ID, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="1"/>
                    <TextBox Text="{Binding FirstName, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="2"/>
                    <TextBox Text="{Binding LastName, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="3"/>
                    <TextBox Text="{Binding Address, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="4"/>
                    <StackPanel Orientation="Horizontal"  Grid.Column="1" Grid.Row="5">
                        <RadioButton Name="radMale" GroupName="Gender" Content="Male" IsChecked="{Binding Male, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}"></RadioButton>
                        <RadioButton Name="radFemale" GroupName="Gender" Content="Female" IsChecked="{Binding Female, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}"></RadioButton>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal"  Grid.Column="1" Grid.Row="6">
                        <CheckBox IsChecked="{Binding Hindi, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}">Hindi</CheckBox>
                        <CheckBox IsChecked="{Binding English, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}">English</CheckBox>
                        <CheckBox IsChecked="{Binding French, BindingGroupName=Group1, UpdateSourceTrigger=Explicit}">French</CheckBox>
                    </StackPanel>
                    <ComboBox DisplayMemberPath="Nationality" SelectedValuePath="Nationality" SelectedValue="{Binding Nationality}"  ItemsSource="{Binding DataContext.NationalityList, UpdateSourceTrigger=Explicit, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" Margin="5,0,0,5" VerticalAlignment="Top" Grid.Column="1" Grid.Row="7"/>
                    <DatePicker x:Name="dpDOB" Grid.Column="1" Grid.Row="8" HorizontalAlignment="Left"
                               SelectedDateFormat="Short"  SelectedDate="{Binding DOB, Mode=TwoWay}"/>
                    <StackPanel Orientation="Horizontal" Grid.Row="10" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="5,5,5,5">
                        <Button Foreground="White" Background="Green" Content="Cancel" Command="{Binding DataContext.CancelCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>
                        <Button Foreground="White" Background="Green" Content="Delete" Command="{Binding DataContext.DeleteUserCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>
                        <Button Foreground="White" Background="Green" Content="Save" Command="{Binding DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="4,0"/>
                    </StackPanel>
                </Grid>
            </Border>
        </DataTemplate>
    </Window.Resources>

Add the below line of code just after the Data Grid.

<ItemsControl BindingGroup="{Binding UpdateBindingGroup, Mode=OneWay}" ItemTemplate="{StaticResource UserGrid}" ItemsSource="{Binding SelectedEmployee, Converter={StaticResource SelectedItemToItemsSource}}" VerticalAlignment="Top" Margin="5,5,5,5"/>

Helper class is used to converts SelectedItem to a collection, for use in the ItemsControl.
Add the Helper class reference to the MainWindow.xaml.

xmlns:helpers="clr-namespace:WpfCrudeOperations.Helpers"

Create a Converters.cs class in the Helpers folder and add the below line of code in the class file

 public class SelectedItemToItemsSource : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null) return null;
            return new List<object>() { value };
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

ViewModelUser uses a ViewModelBase.cs class to implement INotifyPropertyChanged event. Create a ViewModelBase.cs class inside ViewModel folder in your application.

 class ViewModelBase : INotifyPropertyChanged
    {
        //basic ViewModelBase
        internal void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        //Extra Stuff, shows why a base ViewModel is useful
        bool? _CloseWindowFlag;
        public bool? CloseWindowFlag
        {
            get { return _CloseWindowFlag; }
            set
            {
                _CloseWindowFlag = value;
                RaisePropertyChanged("CloseWindowFlag");
            }
        }

        public virtual void CloseWindow(bool? result = true)
        {
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
            {
                CloseWindowFlag = CloseWindowFlag == null
                    ? true
                    : !CloseWindowFlag;
            }));
        }
    }

Buttons “Add Employee”, “Save”, “Cancel” and “Delete” uses Relay command to communicate with ViewModel.
Add the below line of code in ViewModelUser.cs class.

 public RelayCommand CancelCommand { get; set; }
 public RelayCommand SaveCommand { get; set; }
 public RelayCommand AddUserCommand { get; set; }
 public RelayCommand DeleteUserCommand { get; set; }

To call these commands we have to declared methods for these commands on ViewModelUser constructor.

 CancelCommand = new RelayCommand(DoCancel);
 SaveCommand = new RelayCommand(DoSave);
 AddUserCommand = new RelayCommand(AddUser);
 DeleteUserCommand = new RelayCommand(DeleteUser);

Define methods

 void DoCancel(object param)
{
    UpdateBindingGroup.CancelEdit();
    if (SelectedIndex == -1)    //This only closes if new - just to show you how CancelEdit returns old values to bindings
        SelectedEmployee = null;
}

void DoSave(object param)
{
    UpdateBindingGroup.CommitEdit();
    var employee = SelectedEmployee as User;
    if (SelectedIndex == -1)
    {
        personnel.AddEmployee(employee);
        RaisePropertyChanged("Employee"); // Update the list from the data source
    }
    else
        personnel.UpdateEmployee(employee);

    SelectedEmployee = null;
}

void AddUser(object parameter)
{
    SelectedEmployee = null; // Unselects last selection. Essential, as assignment below won't clear other control's SelectedItems
    var employee = new User();
    SelectedEmployee = employee;
}

void DeleteUser(object parameter)
{
    var employee = SelectedEmployee as User;
    if (SelectedIndex != -1)
    {
        personnel.DeleteEmployee(employee);
        RaisePropertyChanged("Employee"); // Update the list from the data source
    }
    else
        SelectedEmployee = null; // Simply discard the new object
}

Add RelayCommand.cs class file in ViewModel Folder in your application.

class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion // Fields

    #region Constructors

    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;
    }
    #endregion // Constructors

    #region ICommand Members

    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);
    }

    #endregion // ICommand Members
}

To Populate Nationality ComboBox. Write the below code in ViewModelUser.cs class.

  public ObservableCollection<NationalityCollection> NationalityList
     {
        get
          {
              _nationalityCollection = new ObservableCollection<NationalityCollection>(personnel.GetNationality());
               return _nationalityCollection;
          }
     }

Add a new class NationalityCollection.cs in Model folder to get Nationality collection.

class NationalityCollection : INotifyPropertyChanged
{
    ICollectionView _nationalityCollection;
    public ICollectionView NationalityView
    {
        get { return _nationalityCollection; }
        set
        {
            if (value != _nationalityCollection)
            {
                _nationalityCollection = value;
                NotifyOfPropertyChange("NationalityCollection");
            }
        }
    }

    public string Nationality
    {
        get { return _nationality; }
        set
        {
            _nationality = value;
            NotifyOfPropertyChange("Nationality");
        }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    private string _nationality;

    private void NotifyOfPropertyChange(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

Add below methods in the PersonnelBusinessObject.cs class

List<NationalityCollection> NationalityCollection { get; set; }
public List<NationalityCollection> GetNationality()
{
    return NationalityCollection = DatabaseLayer.GetNationality();
}
public void AddEmployee(User employee)
{
    DatabaseLayer.InsertEmployee(employee);
    OnEmployeeChanged();
}

public void UpdateEmployee(User employee)
{
    DatabaseLayer.UpdateEmployee(employee);
    OnEmployeeChanged();
}

public void DeleteEmployee(User employee)
{
    DatabaseLayer.DeleteEmployee(employee);
    OnEmployeeChanged();
}

void OnEmployeeChanged()
{
    if (EmployeeChanged != null)
        EmployeeChanged(this, null);
}

Add below methods in DatabaseLayer.cs class

internal static void InsertEmployee(User employee)
{
    try
    {
        SqlParameter[] MyParams = new SqlParameter[8];
        MyParams[0] = new SqlParameter("@ID", employee.ID);
        MyParams[1] = new SqlParameter("@FirstName", employee.FirstName);
        MyParams[2] = new SqlParameter("@LastName", employee.LastName);
        MyParams[3] = new SqlParameter("@Gender", employee.Gender);
        MyParams[4] = new SqlParameter("@DOB", employee.DOB);
        MyParams[5] = new SqlParameter("@Language", employee.Language);
        MyParams[6] = new SqlParameter("@Nationality", employee.Nationality);
        MyParams[7] = new SqlParameter("@Address", employee.Address);
        SqlHelper.ExecuteNonQuery(AppConstants.getConnectionString(), CommandType.StoredProcedure, "[dbo].[uspInsertUser]", MyParams);
        MessageBox.Show("Data Saved Successfully.");
    }
    catch (SqlException ex)
    {
        throw ex;
    }
    finally
    {

    }
}

internal static void UpdateEmployee(User employee)
{
    try
    {
        SqlParameter[] MyParams = new SqlParameter[8];
        MyParams[0] = new SqlParameter("@ID", employee.ID);
        MyParams[1] = new SqlParameter("@FirstName", employee.FirstName);
        MyParams[2] = new SqlParameter("@LastName", employee.LastName);
        MyParams[3] = new SqlParameter("@Gender", employee.Gender);
        MyParams[4] = new SqlParameter("@DOB", employee.DOB);
        MyParams[5] = new SqlParameter("@Language", employee.Language);
        MyParams[6] = new SqlParameter("@Nationality", employee.Nationality);
        MyParams[7] = new SqlParameter("@Address", employee.Address);
        SqlHelper.ExecuteNonQuery(AppConstants.getConnectionString(), CommandType.StoredProcedure, "[dbo].[uspInsertUser]", MyParams);
        MessageBox.Show("Data Updated Successfully.");
    }
    catch (SqlException ex)
    {
        throw ex;
    }
    finally
    {

    }
}

internal static void DeleteEmployee(User employee)
{
    try
    {
        SqlParameter[] MyParams = new SqlParameter[1];
        MyParams[0] = new SqlParameter("@ID", employee.ID);
        SqlHelper.ExecuteNonQuery(AppConstants.getConnectionString(), CommandType.StoredProcedure, "[dbo].[uspDeletetUser]", MyParams);
        MessageBox.Show("Data Deleted Successfully.");
    }
    catch (SqlException ex)
    {
        throw ex;
    }
    finally
    {

    }
}
public static List<NationalityCollection> GetNationality()
{
    try
    {
        DataTable dt = SqlHelper.ExecuteDataTable(AppConstants.getConnectionString(), CommandType.StoredProcedure, "[dbo].[uspGetNationality]");
        var NationalityList = new List<NationalityCollection>();
        foreach (DataRow row in dt.Rows)
        {
            var obj = new NationalityCollection()
            {
                Nationality = (string)row["Nationality"]
            };
            NationalityList.Add(obj);
        }
        return NationalityList;
        // return dt;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

To Implement employee change event. add these line of code in ViewModelUser class constructor.

personnel.EmployeeChanged += new EventHandler(personnel_EmployeeChanged);
UpdateBindingGroup = new BindingGroup { Name = "Group1" };

Method “personnel_EmployeeChanged” definition.

 void personnel_EmployeeChanged(object sender, EventArgs e)
     {
         Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
          {
              RaisePropertyChanged("Employee");
          }));
     }
BindingGroup _UpdateBindingGroup;
public BindingGroup UpdateBindingGroup
{
    get
    {
        return _UpdateBindingGroup;
    }
    set
    {
        if (_UpdateBindingGroup != value)
        {
            _UpdateBindingGroup = value;
            RaisePropertyChanged("UpdateBindingGroup");
        }
    }
}

To get the selected employee from the data grid. Add the below code in ViewModelUser class.

public int SelectedIndex { get; set; }
object _SelectedEmployee;
public object SelectedEmployee
{
    get
    {
        return _SelectedEmployee;
    }
    set
    {
        if (_SelectedEmployee != value)
        {
            _SelectedEmployee = value;
            RaisePropertyChanged("SelectedEmployee");
        }
    }
}

SQL Helper Class
http://www.codesolution.org/sql-helper-class-in-asp-net/

After building and running the application result will be as.

Employee View

Employee View

35 thoughts on “CRUD Operations in WPF with MVVM Framework

  1. mahendra

    very nice article ,i have tried it but not able to implement it on my system,can you please send whole source code on above mentioned email address

  2. jyoti

    The article is very useful. I am implementing the code but at some places I m facing problems. I would be grateful to you if you could send me the source code.

  3. NK Kaushik

    there is no mention anywhere about code of stored procedures
    script for creating SP must be provided

    1. Hitesh Kumar Post author

      AppConstants file contains only connection to database. You can simply add your connection string.

Comments are closed.