Full CRUD Project Walkthrough

Advanced 30 min read Lesson 7 of 7

Let's put everything from this module together: a Student Manager app with a grid, add/edit/delete, and a live SQL Server connection.

Form layout

  • txtFirstName, txtLastName, txtEmail — TextBoxes
  • btnSave, btnDelete, btnClear — Buttons
  • dgvStudents — DataGridView, Dock = Fill in a panel

The full code-behind

using System.Data;
using Microsoft.Data.SqlClient;

public partial class MainForm : Form
{
    private const string ConnectionString =
        "Server=localhost\\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;TrustServerCertificate=True;";

    private int? _selectedStudentId = null;

    public MainForm()
    {
        InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        LoadStudents();
    }

    private void LoadStudents()
    {
        using var connection = new SqlConnection(ConnectionString);
        var adapter = new SqlDataAdapter(
            "SELECT StudentId, FirstName, LastName, Email FROM Students ORDER BY LastName",
            connection);

        var table = new DataTable();
        adapter.Fill(table);
        dgvStudents.DataSource = table;
    }

    private void dgvStudents_SelectionChanged(object sender, EventArgs e)
    {
        if (dgvStudents.CurrentRow == null) return;

        _selectedStudentId = (int)dgvStudents.CurrentRow.Cells["StudentId"].Value;
        txtFirstName.Text = dgvStudents.CurrentRow.Cells["FirstName"].Value?.ToString();
        txtLastName.Text = dgvStudents.CurrentRow.Cells["LastName"].Value?.ToString();
        txtEmail.Text = dgvStudents.CurrentRow.Cells["Email"].Value?.ToString();
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrWhiteSpace(txtFirstName.Text) ||
            string.IsNullOrWhiteSpace(txtLastName.Text) ||
            string.IsNullOrWhiteSpace(txtEmail.Text))
        {
            MessageBox.Show("All fields are required.", "Validation",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        using var connection = new SqlConnection(ConnectionString);
        connection.Open();

        SqlCommand command;

        if (_selectedStudentId == null)
        {
            command = new SqlCommand(
                "INSERT INTO Students (FirstName, LastName, Email) VALUES (@FirstName, @LastName, @Email)",
                connection);
        }
        else
        {
            command = new SqlCommand(
                "UPDATE Students SET FirstName = @FirstName, LastName = @LastName, Email = @Email WHERE StudentId = @StudentId",
                connection);
            command.Parameters.AddWithValue("@StudentId", _selectedStudentId.Value);
        }

        command.Parameters.AddWithValue("@FirstName", txtFirstName.Text.Trim());
        command.Parameters.AddWithValue("@LastName", txtLastName.Text.Trim());
        command.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());

        command.ExecuteNonQuery();

        MessageBox.Show("Saved successfully.");
        ClearForm();
        LoadStudents();
    }

    private void btnDelete_Click(object sender, EventArgs e)
    {
        if (_selectedStudentId == null)
        {
            MessageBox.Show("Select a student first.");
            return;
        }

        var confirm = MessageBox.Show("Delete this student?", "Confirm",
            MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

        if (confirm != DialogResult.Yes) return;

        using var connection = new SqlConnection(ConnectionString);
        connection.Open();

        using var command = new SqlCommand(
            "DELETE FROM Students WHERE StudentId = @StudentId", connection);
        command.Parameters.AddWithValue("@StudentId", _selectedStudentId.Value);
        command.ExecuteNonQuery();

        ClearForm();
        LoadStudents();
    }

    private void btnClear_Click(object sender, EventArgs e)
    {
        ClearForm();
    }

    private void ClearForm()
    {
        _selectedStudentId = null;
        txtFirstName.Clear();
        txtLastName.Clear();
        txtEmail.Clear();
        dgvStudents.ClearSelection();
    }
}

What this demonstrates

  • Loading and refreshing a DataGridView (Lesson 5)
  • Reacting to grid selection to populate an edit form (Lesson 5)
  • One Save button that intelligently INSERTs or UPDATEs depending on whether something is selected
  • Parameterized commands throughout — no SQL injection risk (Module 8)
  • MessageBox confirmations before destructive actions (Lesson 4)

Ideas to extend it yourself

  • Add a search TextBox that filters the grid as you type
  • Add a Courses ComboBox and an Enrollments grid on a second tab
  • Add the RDLC report from the next module, printable from this same form
Key Takeaway

You can now build a full data-driven desktop app with CRUD operations using Windows Forms and SQL Server.

Test Your Knowledge - Take Quiz