Build Your Own Navigation Bar in WPF with Insert / Save / Delete Action

Some time ago, we built a navigation bar for our WPF application to navigate data. We can make it even more powerful, and add CRUD support into it. Because we are using Entity Data Framework, it’s pretty easy to achieve this. Don’t believe it? Let’s first add the following buttons into our navigation bar we built late time:

        <StackPanel Height="28" HorizontalAlignment="Left" Margin="103,232,0,0" Name="stackPanel2" VerticalAlignment="Top" Width="119" Orientation="Horizontal">

            <Button Background="BlanchedAlmond" Content="Insert" FontWeight="Bold" Height="23" Name="insertButton" Width="Auto" Click="insertButton_Click" /> 

            <Button Background="BlanchedAlmond" Content="Save" FontWeight="Bold" Height="23" Name="saveButton" Width="Auto" Click="saveButton_Click"/>

           <Button Background="BlanchedAlmond" Content="Delete" FontWeight="Bold" Height="23" Name="deleteButton" Width="Auto" Click="deleteButton_Click" />

        </StackPanel>

It’s something like below:

clip_image002 

Now let’s add the following event handler methods for each button:

1. Insert button. Insert button adds a new empty entry for users to fill in data.

What we do here is pretty simple. We leverage the method IEditableCollectionViewSource.AddNew() to create a new entry into the current CollectionView. More info can be found here. Because the EmployeeID is assigned in the table automatically when a new row is inserted, we don’t need users to fill in this item.  

 

The code looks like below:

C#:

        private void insertButton_Click(object sender, RoutedEventArgs e)

        {

            ((BindingListCollectionView)(employeesViewSource__NorthwindEntities.View)).AddNew();

            employeeIDTextBox.Text = "{Auto-assigned}";

        }

    VB:

    Private Sub insertButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

        CType(EmployeesViewSource__NorthwindEntities.View, BindingListCollectionView).AddNew()

        employeeIDTextBox.Text = "{Auto-assigned}"

    End Sub

2. Save button. Save button saves the current data into database.

Let’s use ObjectContext.SaveChanges() to persist all updates to the database. SaveChanges method has an overload version SaveChanges(Boolean). If Boolean is set to false, then you have to call AccetpAllChanges() after calling SaveChanges(Boolean). For more information about this method, please check here.  

 

Here we also need to consider about concurrency errors. For more information about how to handle this, please see here.  

 

The code looks like below:

 

C#:

        private void saveButton_Click(object sender, RoutedEventArgs e)

        {

            try

            {

                northwindEntities.SaveChanges();

                // Update the number of rows in the table in case it's updated by data insertion.

                UpdateNavigatorUI();

            }

            catch (DBConcurrencyException ex)

            {

                // Add business logic code to resolve the concurrency violation...

            } 

        }

     VB:

    Private Sub saveButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

        Try

            NorthwindEntities.SaveChanges()

           ' Update the number of rows in the table in case it's updated by data insertion.

            UpdateNavigatorUI()

        Catch ex As System.Data.DBConcurrencyException

            ' Add business logic code to resolve the concurrency violation...

        End Try

    End Sub

3. Delete button. Delete button tends to delete the current entry.  

Here we instantiate an Employee object with the current item in the form and then use DeleteObject(TEntity) to do the deletion. However, the job isn’t submitted until users click Save button.

 

C#:

        private void deleteButton_Click(object sender, RoutedEventArgs e)

        {

            Employee employee = employeesViewSource__NorthwindEntities.View.CurrentItem as Employee;

            if (employee != null)

      {

    northwindEntities.DeleteObject(employee);

}  

            // Update the row count number and the current row number in the navigation bar.

            UpdateNavigatorUI();

        }  

   VB:

    Private Sub deleteButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

        Dim employee As Employee = CType(EmployeesViewSource__NorthwindEntities.View.CurrentItem, Employee)

        If Not (employee Is Nothing) Then

            NorthwindEntities.DeleteObject(employee)

        End If

        ' Update the row count number and the current row number in the navigation bar

        UpdateNavigatorUI()

    End Sub

Done! Now we can hit F5 and play with it. Have fun!