Essential WinForms Development Techniques in C#

C# WinForms Development Techniques:

1. Control Z-Order Management

// Demonstrating control layering in WinForms
panel1.Controls.Add(buttonA);
panel1.Controls.Add(buttonB);
panel1.Controls.Add(buttonC);

// Move buttonB to the back
buttonB.SendToBack();

// Move buttonC to the front
buttonC.BringToFront();

// The resulting z-order will be: buttonC, buttonA, buttonB

2. ComboBox Item Selecsion by Text

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
    }
 
    private void searchButton_Click(object sender, EventArgs e)
    {
        string searchTerm = searchTextBox.Text;
        int foundIndex = productComboBox.FindString(searchTerm);
        
        if (foundIndex == -1)
        {
            MessageBox.Show("Item not found in the list");
            return;
        }
        
        Product selectedProduct = productComboBox.Items[foundIndex] as Product;
        MessageBox.Show($"Selected: {selectedProduct.Name}");
    }
 
    private void MainForm_Load(object sender, EventArgs e)
    {
        List<Product> products = new List<Product>();
        for (int i = 0; i < 10; i++)
            products.Add(new Product { 
                Name = $"Product{i + 1}", 
                Id = i + 1 
            });
        
        productComboBox.DataSource = products;
        productComboBox.DisplayMember = "Name";
        productComboBox.ValueMember = "Id";
    }
}
 
class Product
{
    public string Name { get; set; }
    public int Id { get; set; }
    public override string ToString()
    {
        return Name;
    }
}

3. Loading Images into PictureBox Control

// Method 1: Absolute file path
pictureBox1.Image = Image.FromFile(@"C:\Images\photo.jpg");

// Method 2: Relative path from application directory
string imagePath = Path.Combine(Application.StartupPath, "Images", "photo.jpg");
pictureBox1.Image = Image.FromFile(imagePath);

// Method 3: Loading from web URL
string imageUrl = "https://example.com/image.png";
using (var webClient = new WebClient())
{
    using (var stream = webClient.OpenRead(imageUrl))
    {
        pictureBox1.Image = Image.FromStream(stream);
    }
}

4. Generating QR Codes with Text Overlay

public class QRCodeGenerator
{
    // Requires QrCode.net NuGet package
    // Add these namespaces:
    // using Gma.QrCodeNet.Encoding;
    // using Gma.QrCodeNet.Encoding.Windows.Render;
    // using System.Drawing.Imaging;
    // using System.IO;
    // using System.Drawing;

    public static void CreateQRCodeWithText(string content, string outputPath)
    {
        QrEncoder encoder = new QrEncoder(ErrorCorrectionLevel.M);
        QrCode qrCode = encoder.Encode(content);
        
        GraphicsRenderer renderer = new GraphicsRenderer(
            new FixedModuleSize(15, QuietZoneModules.Two), 
            Brushes.Black, 
            Brushes.White);
        
        using (FileStream outputStream = new FileStream(outputPath, FileMode.Create))
        {
            renderer.WriteToStream(qrCode.Matrix, ImageFormat.Png, outputStream);
        }
        
        AddTextOverlay(content, outputPath);
    }

    private static void AddTextOverlay(string text, string filePath)
    {
        Font textFont = new Font("Arial", 12, FontStyle.Regular);
        SolidBrush textBrush = new SolidBrush(Color.Black);
        
        try
        {
            Bitmap qrImage = new Bitmap(filePath);
            Bitmap combinedImage = new Bitmap(250, 290);
            Graphics graphics = Graphics.FromImage(combinedImage);
            graphics.Clear(Color.White);
            
            graphics.DrawString(text, textFont, textBrush, 
                new PointF((combinedImage.Width - text.Length * 8) / 2, combinedImage.Height - 30));
            
            graphics.DrawImage(qrImage, 0, 0, 250, 250);
            qrImage.Dispose();
            
            combinedImage.Save(filePath, ImageFormat.Png);
            graphics.Dispose();
            combinedImage.Dispose();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error adding text overlay: {ex.Message}");
        }
    }
}

5. Adding ToolTips to Buttons

// Method 1: Using designer properties
// In the form designer, add a ToolTip control and set button1's ToolTip on ToolTip1 property

// Method 2: Programmatically setting ToolTip
private void InitializeTooltips()
{
    toolTip1.IsBalloon = true;
    toolTip1.SetToolTip(actionButton, "Click to perform action");
    toolTip1.SetToolTip(helpButton, "Get help information");
}

// Method 3: Dynamic ToolTip creation
private void CreateDynamicTooltip(Control targetControl, string message)
{
    ToolTip dynamicTooltip = new ToolTip();
    dynamicTooltip.IsBalloon = true;
    dynamicTooltip.SetToolTip(targetControl, message);
}

6. Clearing DataGridView Data

// Method 1: Clearing data source
dataGridView1.DataSource = null;

// Method 2: Clearing DataTable while preserving columns
DataTable dataTable = (DataTable)dataGridView1.DataSource;
dataTable.Clear();
dataGridView1.Refresh();

// Method 3: Removing rows individually
while (dataGridView1.Rows.Count > 0)
{
    dataGridView1.Rows.RemoveAt(0);
}

7. DataGridView Data Validation and Traversal

// Method 1: Using primary key for uniqueness
private void SetupDataTableWithPrimaryKey()
{
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("ID", typeof(int));
    dataTable.Columns.Add("Name", typeof(string));
    dataTable.Columns.Add("Value", typeof(decimal));
    
    DataColumn[] primaryKey = new DataColumn[1];
    primaryKey[0] = dataTable.Columns["ID"];
    dataTable.PrimaryKey = primaryKey;
}

// Method 2: Checking for duplicates in a column
private void CheckForDuplicates()
{
    HashSet<string> uniqueValues = new HashSet<string>();
    
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.Cells["Name"].Value != null)
        {
            string currentValue = row.Cells["Name"].Value.ToString();
            
            if (uniqueValues.Contains(currentValue))
            {
                MessageBox.Show($"Duplicate value found: {currentValue}");
                return;
            }
            uniqueValues.Add(currentValue);
        }
    }
}

// Method 3: Cell value change validation
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.Rows.Count > 1 && e.RowIndex > 0)
    {
        string currentValue = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString();
        
        for (int i = 0; i < e.RowIndex; i++)
        {
            if (dataGridView1.Rows[i].Cells[e.ColumnIndex].Value?.ToString() == currentValue)
            {
                MessageBox.Show("This value already exists!", "Validation Error");
                dataGridView1.CancelEdit();
                break;
            }
        }
    }
}

8. Displaying Row Numbers in DataGridView

// Method 1: Drawing row numbers without a dedicated column
private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    Rectangle rowNumberBounds = new Rectangle(
        e.RowBounds.Location.X,
        e.RowBounds.Location.Y,
        dataGridView1.RowHeadersWidth - 5,
        e.RowBounds.Height);
    
    TextRenderer.DrawText(e.Graphics, 
        (e.RowIndex + 1).ToString(),
        dataGridView1.RowHeadersDefaultCellStyle.Font,
        rowNumberBounds,
        dataGridView1.RowHeadersDefaultCellStyle.ForeColor,
        TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
}

// Method 2: Using a dedicated "Row Number" column
private void InitializeRowNumberColumn()
{
    DataGridViewTextBoxColumn rowNumberColumn = new DataGridViewTextBoxColumn();
    rowNumberColumn.HeaderText = "Row #";
    rowNumberColumn.Name = "RowNumber";
    rowNumberColumn.ReadOnly = true;
    rowNumberColumn.Width = 50;
    dataGridView1.Columns.Insert(0, rowNumberColumn);
    
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        row.Cells["RowNumber"].Value = row.Index + 1;
    }
}

9. Parent-Child Form Communication

// Parent form to child form communication
public partial class ParentForm : Form
{
    public ParentForm()
    {
        InitializeComponent();
    }
    
    private void openChildButton_Click(object sender, EventArgs e)
    {
        // Method 1: Using constructor parameters
        ChildForm childForm = new ChildForm(parentDataTextBox.Text);
        childForm.Show();
        
        // Method 2: Using properties
        ChildForm childForm2 = new ChildForm();
        childForm2.ChildData = parentDataTextBox.Text;
        childForm2.Show();
        
        // Method 3: Using Owner property
        ChildForm childForm3 = new ChildForm();
        childForm3.Owner = this;
        childForm3.Show();
    }
}

public partial class ChildForm : Form
{
    public ChildForm()
    {
        InitializeComponent();
    }
    
    // Constructor with parameter
    public ChildForm(string initialData)
    {
        InitializeComponent();
        childDataTextBox.Text = initialData;
    }
    
    // Property for data transfer
    public string ChildData
    {
        set { childDataTextBox.Text = value; }
        get { return childDataTextBox.Text; }
    }
    
    private void sendDataBackButton_Click(object sender, EventArgs e)
    {
        // Send data back to parent
        ParentForm parent = (ParentForm)this.Owner;
        parent.ParentData = childDataTextBox.Text;
        this.Close();
    }
}

// Child form to parent form communication
public partial class ParentForm : Form
{
    public string ParentData { get; set; }
    
    private void receiveDataFromChild(object sender, ChildDataEventArgs e)
    {
        parentDataTextBox.Text = e.Data;
    }
}

10. Dynamic Control Removal

// Efficient control removal from a container
private void RemoveSpecificControls(Panel container, string controlPrefix)
{
    // First collect matching controls
    List<Control> controlsToRemove = new List<Control>();
    
    foreach (Control control in container.Controls)
    {
        if (control.Name.StartsWith(controlPrefix))
        {
            controlsToRemove.Add(control);
        }
    }
    
    // Then remove them
    foreach (Control control in controlsToRemove)
    {
        container.Controls.Remove(control);
        control.Dispose();
    }
}

// Usage example
private void ClearDynamicButtons()
{
    RemoveSpecificControls(buttonPanel, "DynamicButton");
}

Tags: WinForms C# .NET DataGridView PictureBox

Posted on Sat, 18 Jul 2026 17:16:01 +0000 by tomtomdotcom