C# WPF List Application

Using a "DataGrid"

Overview

This project is a basic WPF application that follows the four basics of persistent data storage: create, read, update and delete. In this example, a list of employees can be managed directly on the user interface.

The project does the following:

  • Show a list of existing employees when the application runs.
  • A new employee can be added to the list when you enter a name, address and hobby in the textboxes.
  • Clicking on a row will show the information about the employee listed on that row.
  • You can edit an employee's information by clicking their row on the grid, changing the information in the textboxes and clicking Update button.
  • You can delete an employee by selecting them on the list and clicking the Delete button.

Running the Application

image.png This is the user interface shown when you start up the application. A hard-coded list of employees already exists in the DataGrid.

image.png When you click a row on the list, a message will pop up and the employee's information will be displayed in the message box.

image.png

image.png You can add a new employee by entering information into the text fields and clicking the "Add" button.

image.png

image.png You can delete an employee on the list by selecting their row and clicking on the "Delete" Button.

image.png

image.png Finally, you can update employee information by selecting their row, modify the existing information in the editable text fields and clicking the "Update" button.

image.png The application prevents you from creating, updating or deleting employees from the list when fields are incomplete. These error messages direct the user to the steps that they need to take to complete their desired actions.

XAML

<Window x:Class="Test.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:Lab1_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DataGrid x:Name="dg_employees" 
                  HorizontalAlignment="Left" 
                  Height="282" 
                  Margin="56,74,0,0" 
                  VerticalAlignment="Top" 
                  Width="403"
                  ItemsSource="{Binding}"
                  AutoGenerateColumns="False"
                  SelectionChanged="dg_employees_SelectionChanged">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding EmployeeName}" Width="*" IsReadOnly="True"/>
                <DataGridTextColumn Header="Address" Binding="{Binding EmployeeAddress}" Width="*" IsReadOnly="True"/>
                <DataGridTextColumn Header="Hobby" Binding="{Binding EmployeeHobby}" Width="*" IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="addBtn" Content="Add" HorizontalAlignment="Left" Margin="486,200,0,0" VerticalAlignment="Top" Width="268" Click="addBtn_Click"/>
        <Button x:Name="deleteBtn" Content="Delete" HorizontalAlignment="Left" Margin="486,250,0,0" VerticalAlignment="Top" Width="268" Click="deleteBtn_Click"/>
        <Button x:Name="updateBtn" Content="Update" HorizontalAlignment="Left" Margin="486,300,0,0" VerticalAlignment="Top" Width="268" Click="updateBtn_Click"/>
        <Button x:Name="exitBtn" Content ="Exit" HorizontalAlignment="Left" Margin="486,350,0,0" VerticalAlignment="Top" Width="268" Click="exitBtn_Click"/>
        <TextBox x:Name="name_Txt" HorizontalAlignment="Left" Height="23" Margin="586,78,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="168"/>
        <Label x:Name="nameLabel" Content="Name:" HorizontalAlignment="Left" Margin="486,74,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="address_Txt" HorizontalAlignment="Left" Height="22" Margin="586,110,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="168"/>
        <Label x:Name="addressLabel" Content="Address:" HorizontalAlignment="Left" Margin="486,106,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="hobby_Txt" HorizontalAlignment="Left" Height="24" Margin="586,140,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="168"/>
        <Label x:Name="hobbyLabel" Content="Hobby:" HorizontalAlignment="Left" Margin="486,136,0,0" VerticalAlignment="Top"/>
        <Label Content="List of Employees:" HorizontalAlignment="Left" Margin="56,43,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window>

Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Test
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LoadEmployees();
        }

        //create employee list
        List<Employee> employees = new List<Employee>();

        //create temporary "selected employee" object
        Employee selectedEmployee = null;

        //method to add hard-coded employee objects
        private void LoadEmployees()
        {
            employees.Add(new Employee
            {
                EmployeeName = "Richard Dalmacio",
                EmployeeAddress = "Fake Address 1",
                EmployeeHobby = "Video games"
            }) ;

            employees.Add(new Employee
            {
                EmployeeName = "Robert Dalmacio",
                EmployeeAddress = "Fake Address 2",
                EmployeeHobby = "Listening to music"
            });

            //create datagrid itemsource
            dg_employees.ItemsSource = employees;
        }

        private void addBtn_Click(object sender, RoutedEventArgs e)
        {
            if (name_Txt.Text == "" || address_Txt.Text == "" || hobby_Txt.Text == "")
            {
                //prompt to ensure all fields have input
                MessageBox.Show("Please, fill empty fields with input.");
            }
            else
            {
                //add new employee to the list 
                employees.Add(new Employee
                {
                    EmployeeName = name_Txt.Text,
                    EmployeeAddress = address_Txt.Text,
                    EmployeeHobby = hobby_Txt.Text,
                });

                //refresh datagrid
                dg_employees.ItemsSource = null;
                dg_employees.ItemsSource = employees;

                //output
                MessageBox.Show("Employee added.");
                ClearAll();
            }
        }

        private void deleteBtn_Click(object sender, RoutedEventArgs e)
        {
            //create new employee object based on the SELECTED row
            Employee employeeToRemove = dg_employees.SelectedItem as Employee;

            if (selectedEmployee == null)
            {
                //prompt for selection of a row before deletion occurs
                MessageBox.Show("Please select a row before deleting.");
            }
            else
            {
                for (int i = 0; i < employees.Count; i++)
                {
                    //the following if statement checks if ALL the selected employee's properties match to prevent employees with the same name, address and hobby to be deleted
                    if (employees[i].EmployeeName.Equals(selectedEmployee.EmployeeName) && employees[i].EmployeeAddress.Equals(selectedEmployee.EmployeeAddress) && employees[i].EmployeeHobby.Equals(selectedEmployee.EmployeeHobby))
                    {
                        //removes employee from the list
                        employees.RemoveAt(i);

                        //refresh datagrid
                        dg_employees.ItemsSource = null;
                        dg_employees.ItemsSource = employees;

                        //output
                        MessageBox.Show("Employee deleted.");
                        ClearAll();

                        //the break is just here to make sure to stop the loop ...
                        //after the deletion is complete
                        break;
                    }
                }
            }
        }

        private void updateBtn_Click(object sender, RoutedEventArgs e)
        {
            if (selectedEmployee == null)
            {
                //prompt to ensure user selects a row to update first
                MessageBox.Show("Please, select a row to update.");
            }
            else if (selectedEmployee != null)
            {
                //figure out where the object is in the list using the selected row
                int index = employees.IndexOf(selectedEmployee);

                //change the object's information based on input in the text
                employees[index].EmployeeName = name_Txt.Text;
                employees[index].EmployeeAddress = address_Txt.Text;
                employees[index].EmployeeHobby = hobby_Txt.Text;

                //refresh list of employees
                dg_employees.ItemsSource = null;
                dg_employees.ItemsSource = employees;

                //output
                MessageBox.Show("Employee information updated.");
                ClearAll();
            }
        }

        private void exitBtn_Click(object sender, RoutedEventArgs e)
        {
            //output
            MessageBox.Show("You have ended the application. Good-bye!");
            this.Close();
        }

        //method used to determine which object in the datagrid is selected
        private void dg_employees_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dg_employees.CurrentItem != null)
            {
                try
                {
                    selectedEmployee = (Employee)dg_employees.CurrentItem;
                    name_Txt.Text = selectedEmployee.EmployeeName;
                    address_Txt.Text = selectedEmployee.EmployeeAddress;
                    hobby_Txt.Text = selectedEmployee.EmployeeHobby;
                    MessageBox.Show(selectedEmployee.Details);
                }
                catch (System.InvalidCastException)
                {
                    MessageBox.Show("Exception: Do not click on an empty row.");
                    ClearAll();
                }
            }
        }

        // method that clears all input fields
        public void ClearAll()
        {
            name_Txt.Clear();
            address_Txt.Clear();
            hobby_Txt.Clear();
        }
    }
}

Employee Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Employee 
    {
        //declaration of employee properties
        public string EmployeeName { get; set; }
        public string EmployeeAddress { get; set; }
        public string EmployeeHobby { get; set; }
        public string Details { get { return String.Format("{0} lives in {1} and their hobby is {2}", 
            EmployeeName, EmployeeAddress, EmployeeHobby); } }

        //employee constructor - all 3 properties
        public Employee(string employeeName, string employeeAddress, string employeeHobby)
        {
            this.EmployeeName = employeeName;
            this.EmployeeAddress = employeeAddress;
            this.EmployeeHobby = employeeHobby;
        }

        //default constructor
        public Employee()
        {

        }
    }
}