Sunday, April 22, 2018

Spatial types and functions are not available for this provider because the assembly 'Microsoft.SqlServer.Types' version 10 or higher could not be found.

Hello,

While working with an ASP.NET MVC app using SQL Server 2016, this error appears in the browser "Spatial types and functions are not available for this provider because the assembly 'Microsoft.SqlServer.Types' version 10 or higher could not be found. ". After searching the forums, the solution that worked for me was to add Microsoft.SqlServer.Types dependentAssembly element inside the assemblyBinding node in the web.config.
<dependentAssembly>
        <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
        <bindingRedirect oldVersion="10.0.0.0-11.0.0.0" newVersion="14.0.0.0" />
</dependentAssembly>

Chrome Script Debugging in Visual Studio is Enabled Hangs Up

Good morning!

While using the Visual Studio 2017 to debug ASP.NET MVC applications targeting the Chrome browser, one might encounter that both the IDE and browser hangs up. The workaround is to uncheck the Enable JavaScript debuggin for ASP.NET (Chrome and IE).

Thursday, April 19, 2018

Match Item That Exists In A List Using Regular Expression and LINQ

Hi!
Using Any() in LINQ, we can match/find an item that exists in a List<T> or IEnumerable using Regular Expressions.
if(Products.Any(t => Regex.IsMatch(t, ProductsFromFrance.FrenchProdPattern))
{
   //true statement here..
}
Where Products is the List object and ProductsFromFrance.FrenchProdPattern is the Regular Expression pattern.

Match Network Path In A String Using Regular Expression

Hello,

While working on a project, I was confronted with an issue on how to match or extract a network path. Normally, you can use string functions or built-in .NET code to check the validity of a path, but since I'm also refreshing my skills in Regular Expression. I prefer the latter as the solution. So the pattern to match the server path is presented below:
((\\\\)?((?<Folder>[a-zA-Z0-9- _]+)(\\.*[a-zA-Z0-9-_ \\])(?=")))
And to declare that pattern in your C# code, you have to escape the back slash characters.
string ServerPath = "((\\\\\\\\)?((?<Folder>[a-zA-Z0-9- _]+)(\\\\.*[a-zA-Z0-9-_ \\\\])(?=\")))";
The input strings tested are as follows.
Const ImagesPath As String = "\\ImagesServer\Logo Files\InetPub\TempProjects\"
Const docsPath As String = "\\docsPathServer15\Health\Physicians\"
Const vsPath As String = "\\vsServer909\vs2017\Projects"
string manual = "\\manualServer\CompanyRules\EmployeeFiles\Cebu"; 
The referenced post is here: Pattern Matching Path Files but I made some modifications to get the path inside the enclosing quotes.

Cheers!

Friday, April 13, 2018

How To Update Multiple Rows In One SQL Statement

Here's how to update multiple rows in one SQL statement using MSSQL.
UPDATE
  tblEmp
SET
  empSalary = empSrc.empSalary,
  empLevel = empSrc.empLevel
FROM
  dbo.tblEmployees AS tblEmp
  INNER JOIN
  (
    VALUES
    (001, 10000.00, 10),
    (002, 32000.00, 15),
    (003, 9500.00, 3)
  ) AS empSrc (empID, empSalary, empLevel)
    ON tblEmp.empID = empSrc.empID;
Reference: How to update multiple columns of multiple rows in one SQL statement

Monday, April 9, 2018

MVVM RelayCommand and ViewModelBase Classes in VB.NET

Good evening!
Here's a conversion of the RelayCommand and VewModelBase classes to VB.NET as reference for VB.NET programmers.
RelayCommand
Imports System.Windows.Input

Public Class RelayCommand : Implements ICommand

    Private ReadOnly _execute As Action(Of Object)
    Private ReadOnly _canExecute As Predicate(Of Object)

    Public Sub New(ByVal execute As Action(Of Object))
    End Sub

    Public Sub New(ByVal execute As Action(Of Object), ByVal canExecute As Predicate(Of Object))
        If execute Is Nothing Then Throw New ArgumentNullException("execute")
        _execute = execute
        _canExecute = canExecute
    End Sub

    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
        Return (_canExecute Is Nothing) OrElse _canExecute(parameter)
    End Function

    Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged

        AddHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            CommandManager.InvalidateRequerySuggested()
        End RaiseEvent
    End Event

    Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
        _execute(parameter)
    End Sub
    
End Class
ViewModelBase
Imports System.ComponentModel

Public Class ViewModelBase : Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler _
         Implements INotifyPropertyChanged.PropertyChanged

    Protected Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub
End Class

Thursday, April 5, 2018

Refactor an MVVM ViewModel Class

Good afternoon!
I recently asked the forums on how to refactor a ViewModel class given that in the future additional features or functionalities will be added, so the ViewModel class becomes bloated and hard to trace. All the commands, database operations and properties are declared in this class. So, the option I was thinking was segregation but I also need inputs from other experienced developers in the community.
Sample ViewModel Class
namespace MVVM.MainApplication.ViewModel
{
   public class EmployeeViewModel : ViewModelBase
  {        
        private ICommand _saveCommand;
        private ICommand _resetCommand;
        private ICommand _editCommand;
        private ICommand _deleteCommand;
        private Employee _employeeEntity;
        private EmployeeRepository _repository;
 
        private EmployeeModel _employeeModel;
        public EmployeeModel EmployeeModel
        {
            get
            {
                return _employeeModel;
            }
            set
            {
                _employeeModel = value;
                OnPropertyChanged("EmployeeModel");
            }
        }
 
        private ObservableCollection<EmployeeModel> _employeeModels;
        public ObservableCollection<EmployeeModel> EmployeeModels
        {
            get
            {
                return _employeeModels;
            }
            set
            {
                _employeeModels = value;
                OnPropertyChanged("EmployeeModels");
            }
        } 
 
        private void EmployeeModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged("EmployeeModels");
        }
        
        public EmployeeViewModel()
        {
            EmployeeModel = new EmployeeModel();
            _employeeEntity = new Employee();
            _repository = new EmployeeRepository();
            EmployeeModels = new ObservableCollection<EmployeeModel>();
            EmployeeModels.CollectionChanged += EmployeeModels_CollectionChanged;
            GetAll();//populate grid with student information
        }
        
        public ICommand ResetCommand
        {
            get
            {
                if (_resetCommand == null)
                {
                    _resetCommand = new RelayCommand(param => this.ResetData(), null);
                }
 
                return _resetCommand;
            }
        }
 
        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new RelayCommand(param => this.SaveData(), null);
                }
 
                return _saveCommand;
            }
        }
 
        public ICommand EditCommand
        {
            get
            {
                if (_editCommand == null)
                {
                    _editCommand = new RelayCommand(param => this.EditData((int)param), null);
                }
 
                return _editCommand;
            }
        }
        
        public ICommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                {
                    _deleteCommand = new RelayCommand(param => this.DeleteEmployee((int)param), null);
                }
 
                return _deleteCommand;
            }
        }
        
    // ------------------------------------DB Operations
        private void ResetData()
        {
            EmployeeModel = new EmployeeModel();
        }
 
        private void DeleteEmployee(int id)
        {
            if (MessageBox.Show("Confirm delete of this record?", "Employee", MessageBoxButton.YesNo)
                == MessageBoxResult.Yes)
            {
               //Delete Codes here
            }
        }
 
        private void SaveData()
        {
            if (EmployeeModel != null)
            {
               //Save codes here
            }
        }
 
        private void EditData(int id)
        {
            //Edit Codes here
        }
 
        private void GetAll()
        {
            //Get All codes here
        }
    }
}
After one member gave his advice, I applied it ASAP by separating the properties and commands to it's own classes.
Employee Entity (Employee Properties)
public class EmployeeEntity : ViewModelBase
{
    public EmployeeEntity()
    {
        EmployeeModels = new ObservableCollection<EmployeeModel>();
        EmployeeModels.CollectionChanged += EmployeeModels_CollectionChanged;
    }
    
    private EmployeeModel _employeeModel;
    public EmployeeModel EmployeeModel
    {
        get
        {
            return _employeeModel;
        }
        set
        {
            _studentModel = value;
            OnPropertyChanged("EmployeeModel");
        }
    }
 
    private ObservableCollection<EmployeeModel> _employeeModels;
    public ObservableCollection<EmployeeModel> EmployeeModels
    {
        get
        {
            return _employeeModels;
        }
        set
        {
            _employeeModels = value;
            OnPropertyChanged("EmployeeModels");
        }
    }
 
    private void EmployeesModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        OnPropertyChanged("EmployeeModels");
    }
}
Command Class (Command Properties)
public class EmployeeCommand
{
        private ICommand _saveCommand;
        private ICommand _resetCommand;
        private ICommand _editCommand;
        private ICommand _deleteCommand;
        private EmployeeViewModel _employeeViewModel { get; set; }
 
        public EmployeeCommand(EmployeeViewModel employeeViewModel)
        {
            this._employeeViewModel = employeeViewModel;
        }
 
        public ICommand ResetCommand
        {
            get
            {
                if (_resetCommand == null)
                {
                    _resetCommand = new RelayCommand(param => _employeeViewModel.ResetData(), null);
                }

                return _resetCommand;
            }
        }
 
        public ICommand SaveCommand
        {
            //
        }
 
        public ICommand EditCommand
        {
            //
        }
 
        public ICommand DeleteCommand
        {
            //
        }
    }
View Model Class (Expose the Commands and Employee Entity)
public class EmployeeViewModel
{
    public EmployeeEntity EmployeeEntity { get; set; }
    public EmployeeCommand EmployeeCommand { get; set; }
    
     public EmployeeViewModel()
        {
            EmployeeCommand = new EmployeeCommand(this);
            EmployeeEntity = new EmployeeEntity();
            EmployeeEntity.EmployeeModel = new EmployeeModel();
            GetAll();
        }
        
        private void ResetData()
        {
            //Clear Model Codes
        }
 
        private void DeleteEmployee(int id)
        {
           //Delete Codes...
        }
 
        private void SaveData()
        {
           //Save Codes...
        }
 
        private void EditData(int id)
        {
            //Edit Codes here
        }
 
        private void GetAll()
        {
            //Get All codes here
        }
}

Now my ViewModel class looks cleaner and manageable. Cheers! :-)

Tuesday, April 3, 2018

View attendees of a meeting in Outlook 365

Hello!
While familiarizing myself with Outlook 365, I had difficulty in viewing the attendees of a specific meeting. The layout of Outlook 365 has changed and I didn't see the Tracking button under Meeting Occurrence tab. After doing some research, the solution to show the attendees is to check the Normal option of People Pane under View tab.

Saturday, March 31, 2018

WPF CRUD with DataGrid and Entity Framework (VB.NET)

Good morning!

Here's the VB.NET version of this post WPF CRUD with DataGrid and Entity Framework C#. The steps to accomplish basing from the C# post are:
a. Run the create table script assuming that you haven't created the Students table.
b. Create a VB.NET WPF project.
c. Replace the XAML markup of the window control.
Once done, the scripts for the repository class and window code-behind are as follows:
Repository Class
Public Class StudentRepository

    Private studentContext As StudentEntities = Nothing

    Public Sub New()
        studentContext = New StudentEntities()
    End Sub

    Public Function GetStudent(ByVal id As Integer) As Student
        Return studentContext.Students.Find(id)
    End Function

    Public Function GetAll() As List(Of Student)
        Return studentContext.Students.ToList()
    End Function

    Public Sub AddStudent(ByVal student As Student)
        If student IsNot Nothing Then
            studentContext.Students.Add(student)
            studentContext.SaveChanges()
        End If
    End Sub

    Public Sub UpdateStudent(ByVal student As Student)
        Dim studentFind = Me.GetStudent(student.ID)
        If studentFind IsNot Nothing Then
            studentFind.Name = student.Name
            studentFind.Contact = student.Contact
            studentFind.Age = student.Age
            studentFind.Address = student.Address
            studentContext.SaveChanges()
        End If
    End Sub

    Public Sub RemoveStudent(ByVal id As Integer)
        Dim studObj = studentContext.Students.Find(id)
        If studObj IsNot Nothing Then
            studentContext.Students.Remove(studObj)
            studentContext.SaveChanges()
        End If
    End Sub

End Class
Code Behind
Class MainWindow

    Private studentRepository As StudentRepository

    Private Property Id As Integer

    Public Sub New 
        ' This call is required by the designer.
        InitializeComponent()
        studentRepository  = New StudentRepository()
    End Sub

    Private Sub MainWindow_OnLoaded(sender As Object, e As RoutedEventArgs)
        Id = -1
        PopulateGrid()

    End Sub

    Private Sub PopulateGrid()
        DataGridStudents.ItemsSource = studentRepository.GetAll()
    End Sub
    
    Private Sub ButtonCancel_Click(sender As Object, e As RoutedEventArgs)
        ResetControls()
    End Sub

    Private Sub ResetControls()
        Me.Id = -1
        TextBoxName.Text = String.Empty
        TextBoxAge.Text = String.Empty
        TextBoxAddress.Text = String.Empty
        TextBoxContact.Text = String.Empty
    End Sub

    Private Sub ButtonEdit_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim student = TryCast((CType(sender, FrameworkElement)).DataContext, Student)
        If student IsNot Nothing Then
            TextBoxName.Text = student.Name
            TextBoxAge.Text = student.Age.ToString()
            TextBoxAddress.Text = student.Address
            TextBoxContact.Text = student.Contact
            Me.Id = student.ID
        End If
    End Sub

    Private Sub ButtonSave_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        If Not String.IsNullOrEmpty(TextBoxAddress.Text) AndAlso Not String.IsNullOrEmpty(TextBoxAge.Text) AndAlso Not String.IsNullOrEmpty(TextBoxContact.Text) AndAlso Not String.IsNullOrEmpty(TextBoxName.Text) Then
            Try
                Dim student As Student = New Student() With {.Address = TextBoxAddress.Text, .Age = Convert.ToInt32(TextBoxAge.Text), .Contact = TextBoxContact.Text, .Name = TextBoxName.Text}
                If Me.Id <= 0 Then
                    studentRepository.AddStudent(student)
                    MessageBox.Show("New record successfully saved.")
                Else
                    student.ID = Me.Id
                    studentRepository.UpdateStudent(student)
                    MessageBox.Show("Record successfully updated.")
                End If
            Catch ex As Exception
                MessageBox.Show("An error occured unable to save record!", "", MessageBoxButton.OK, MessageBoxImage.Error)
                Debug.Print(ex.Message)
            Finally
                ResetControls()
                PopulateGrid()
            End Try
        End If
    End Sub

    Private Sub ButtonDelete_OnClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
        If MessageBox.Show("Confirm delete of this record?", "Student", MessageBoxButton.YesNo) = MessageBoxResult.Yes Then
            Dim student = TryCast((CType(sender, FrameworkElement)).DataContext, Student)
            If student IsNot Nothing Then
                Try
                    studentRepository.RemoveStudent(student.ID)
                    MessageBox.Show("Record successfully deleted")
                Catch ex As Exception
                    MessageBox.Show("An error occured. Unable to delete record!", "", MessageBoxButton.OK, MessageBoxImage.Error)
                Finally
                    ResetControls()
                    PopulateGrid()
                End Try
            End If
        End If
    End Sub

End Class
Output

WPF CRUD with DataGrid and Entity Framework

Good evening!

Here's a simple WPF CRUD(Create/Update/Delete) application using DataGrid and Entity Framework. This doesn't involve the MVVM pattern and input validation. Maybe if I have time, in the future I'll post an MVVM equivalent post. So to proceed, execute the SQL script below and make sure to replace the database name with an existing one.
USE [your_database]
GO

/****** Object:  Table [dbo].[Students]    Script Date: 3/31/2018 11:24:23 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Students](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [Name] [varchar](50) NULL,
 [Age] [int] NULL,
 [Address] [varchar](50) NULL,
 [Contact] [varchar](50) NULL,
 CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED 
(
 [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO
Next is create a WPF project and then add an ADO.NET Entity Data Model that connects to the Students table in your database. Once done, add a repository class such as below that performs the CRUD operations.
public class StudentRepository
{
 private StudentEntities studentContext = null;

 public StudentRepository()
 {
  studentContext = new StudentEntities();
 }

 public Student Get(int id)
 {
  return studentContext.Students.Find(id);
 }

 public List<Student> GetAll()
 {
  return studentContext.Students.ToList();
 }

 public void AddStudent(Student student)
 {
  if (student != null)
  {
   studentContext.Students.Add(student);
   studentContext.SaveChanges();
  }
 }

 public void UpdateStudent(Student student)
 {
  var studentFind = this.Get(student.ID);
  if (studentFind != null)
  {
   studentFind.Name = student.Name;
   studentFind.Contact = student.Contact;
   studentFind.Age = student.Age;
   studentFind.Address = student.Address;
   studentContext.SaveChanges();
  }
 }

 public void RemoveStudent(int id)
 {
  var studObj = studentContext.Students.Find(id);
  if (studObj != null)
  {
   studentContext.Students.Remove(studObj);
   studentContext.SaveChanges();
  }
 }
}
In your XAML page, add the markup that includes DataGrid, TextBox and Button controls. These controls are contained in a StackPanel container.
<StackPanel Orientation="Vertical">
        <GroupBox Header="Student Form" Margin="10">
            <Grid Height="150">
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Content="Name" HorizontalAlignment="Left" 
                       VerticalContentAlignment="Center" Grid.Column="0" Grid.Row="0"/>
                <TextBox Grid.Row="0" Grid.Column="1" x:Name="TextBoxName" Height="27" 
                       Margin="5"  Width="300" HorizontalAlignment="Left"/>
                <Label Content="Age" HorizontalAlignment="Left" VerticalContentAlignment="Center" 
                       Grid.Row="1" Grid.Column="0"/>
                <TextBox Grid.Row="1" Grid.Column="1" x:Name="TextBoxAge" Height="27" 
                       Margin="5" Width="70" HorizontalAlignment="Left"/>
                <Label Content="Address" HorizontalAlignment="Left" VerticalContentAlignment="Center" 
                       Grid.Row="2" Grid.Column="0" />
                <TextBox Grid.Row="2" Grid.Column="1" x:Name="TextBoxAddress" Height="27" 
                       Margin="5" Width="300" HorizontalAlignment="Left"/>
                <Label Content="Contact" HorizontalAlignment="Left" VerticalContentAlignment="Center" 
                       Grid.Row="3" Grid.Column="0" />
                <TextBox Grid.Row="3" Grid.Column="1" x:Name="TextBoxContact" Height="27"
                       Margin="5" Width="300" HorizontalAlignment="Left"/>
            </Grid>
        </GroupBox>
        <StackPanel Height="40" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button x:Name="ButtonSave" Content="Save" Height="30" Width="80" Click="ButtonSave_OnClick"/>
            <Button x:Name="ButtonCancel" Content="Cancel" Height="30" Width="80" Margin="5,0,10,0" Click="ButtonCancel_Click"/>
        </StackPanel>
        <StackPanel Height="210">
            <DataGrid x:Name="DataGridStudents" AutoGenerateColumns="False"
                      CanUserAddRows="False" Height="200" Margin="10">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=ID}" Visibility="Hidden"/>
                    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="100"  IsReadOnly="True"/>
                    <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}" Width="50"  IsReadOnly="True"/>
                    <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" Width="180" IsReadOnly="True"/>
                    <DataGridTextColumn Header="Contact" Binding="{Binding Path=Contact}" Width="125" IsReadOnly="True"/>
                    <DataGridTemplateColumn Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Select" x:Name="ButtonEdit" 
                                        Click="ButtonEdit_OnClick"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Width="50">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Delete" x:Name="ButtonDelete"
                                        Click="ButtonDelete_OnClick"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </StackPanel>
In window's code behind, add the codes for the button events and other functionalities.
public partial class MainWindow : Window
    {
        private StudentRepository studentRepository;

        private int Id
        {
            get;
            set;
        }

        public MainWindow()
        {
            InitializeComponent();
            studentRepository = new StudentRepository();
        }

        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            Id = -1;
            PopulateGrid();
        }

        private void PopulateGrid()
        {
            DataGridStudents.ItemsSource = studentRepository.GetAll();
        }

        private void ButtonEdit_OnClick(object sender, RoutedEventArgs e)
        {
            var student = ((FrameworkElement) sender).DataContext as Student;
            if (student != null)
            {
                TextBoxName.Text = student.Name;
                TextBoxAge.Text = student.Age.ToString();
                TextBoxAddress.Text = student.Address;
                TextBoxContact.Text = student.Contact;
                this.Id = student.ID;
            }
        }

        private void ButtonCancel_Click(object sender, RoutedEventArgs e)
        {
            ResetControls();
        }

        private void ResetControls()
        {
            this.Id = -1;
            TextBoxName.Text = string.Empty;
            TextBoxAge.Text = string.Empty;
            TextBoxAddress.Text = string.Empty;
            TextBoxContact.Text = string.Empty;
        }

        private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(TextBoxAddress.Text) && !string.IsNullOrEmpty(TextBoxAge.Text)
                && !string.IsNullOrEmpty(TextBoxContact.Text) && !string.IsNullOrEmpty(TextBoxName.Text))
            {
                try
                {
                    Student student = new Student()
                    {
                        Address = TextBoxAddress.Text,
                        Age = Convert.ToInt32(TextBoxAge.Text),
                        Contact = TextBoxContact.Text,
                        Name = TextBoxName.Text
                    };

                    if (this.Id <= 0) //save
                    {
                        studentRepository.AddStudent(student);
                        MessageBox.Show("New record successfully saved.");
                    }
                    else //save
                    {
                        student.ID = this.Id;
                        studentRepository.UpdateStudent(student);
                        MessageBox.Show("Record successfully updated.");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("An error occured unable to save record!", "",MessageBoxButton.OK,
                        MessageBoxImage.Error);
                    Debug.Print(ex.Message);
                }
                finally
                {
                    ResetControls();
                    PopulateGrid();
                }
            }
        }

        private void ButtonDelete_OnClick(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("Confirm delete of this record?", "Student",MessageBoxButton.YesNo)
                == MessageBoxResult.Yes)
            {
                var student = ((FrameworkElement)sender).DataContext as Student;
                if (student != null)
                {
                    try
                    {
                        studentRepository.RemoveStudent(student.ID);
                        MessageBox.Show("Record successfully deleted");
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("An error occured. Unable to delete record!", "", MessageBoxButton.OK,
                            MessageBoxImage.Error);
                    }
                    finally
                    {
                        ResetControls();
                        PopulateGrid();
                    }
                }
            }
        }
    }
Output
That's it.. :-)