
Building an Inventory Management System Application in WinForms
As a software developer with a passion for creating intuitive desktop applications, I recently embarked on a project to build an Inventory Management System (IMS) using WinForms in C#. This experience has been an exciting journey of exploring new challenges, from managing complex data structures to handling interactions between forms and database queries. In this post, I’ll walk you through the process, the challenges I faced, and the solutions I implemented to build a robust inventory management system.
Project Overview
The goal of the project was to create a system where users could manage parts and products. Each product could have multiple associated parts, and parts could be added, modified, or deleted. Additionally, I needed to handle user interactions with a DataGridView for visualizing products and parts, and ensure the system connected to a SQLite database for data persistence.
Key Features of the Inventory Management System
- Add/Modify Parts and Products: The core functionality allows users to add and modify parts and products. Each product can have multiple associated parts, and the application ensures that relationships between parts and products are respected.
- DataGridView for Data Management: We used a DataGridView to display both parts and products. It’s a flexible UI component that lets users view and interact with large sets of data easily.
- SQLite Integration: The data for parts and products is stored in a SQLite database, ensuring persistent data across sessions.
- Validation and Error Handling: I implemented detailed validation mechanisms to prevent users from entering invalid data, such as negative values for inventory or incorrect formats for pricing.
Key Challenges and Solutions
1. Handling Relationships Between Products and Parts
One of the trickiest parts of this project was managing the relationships between products and their associated parts. For example, a user should not be able to delete a part if it is still associated with a product. To address this, I created a method that checks whether a part is associated with any product before allowing it to be deleted.
public bool IsPartAssociatedWithAnyProduct(int partId)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
string query = "SELECT COUNT(*) FROM ProductParts WHERE PartID = @PartID";
SQLiteCommand command = new SQLiteCommand(query, conn);
command.Parameters.AddWithValue("@PartID", partId);
int count = Convert.ToInt32(command.ExecuteScalar());
return count > 0;
}
}
By ensuring parts that are tied to products cannot be deleted, I maintained data integrity and improved user experience.
2. Managing Data with DataGridView
The DataGridView is an essential component for displaying and managing data in this application. However, one of the main challenges was handling System.FormatException errors when interacting with the grid. These errors occurred when trying to convert cell values that didn’t match the expected format (e.g., empty cells being converted to int
).
To resolve this, I implemented safer data retrieval methods by checking for null or empty values before performing conversions:
if (partIdValue == null || !int.TryParse(partIdValue.ToString(), out int selectedPartId))
{
MessageBox.Show("Invalid Part ID format.");
return;
}
This solution ensures that invalid data doesn’t cause crashes and improves the robustness of the system.
3. Separation of Insert and Update Logic
Initially, I had combined the logic for adding and updating parts and products into single methods. However, this made the code harder to maintain and understand. Based on this realization, I refactored the code to separate the add and update logic for both parts and products.
Here’s an example of how I separated the AddPart and UpdatePart methods in the InventoryDAO class:
public void addPart(Part part)
{
string query = "INSERT INTO Parts (Name, InventoryQty, Price, Min, Max, PartType, MachineID, CompanyName) " +
"VALUES (@Name, @InventoryQty, @Price, @Min, @Max, @PartType, @MachineID, @CompanyName)";
ExecutePartQuery(part, query);
}
public void updatePart(Part part)
{
string query = "UPDATE Parts SET Name = @Name, InventoryQty = @InventoryQty, Price = @Price, Min = @Min, Max = @Max, " +
"PartType = @PartType, MachineID = @MachineID, CompanyName = @CompanyName WHERE PartID = @PartID";
ExecutePartQuery(part, query);
}
By separating these concerns, I made the codebase easier to maintain and debug.
4. Handling Deletions in Associated Parts
Another challenge was ensuring that when a user deletes a product, all associations between that product and its parts are properly removed. I achieved this by implementing a method to delete product-part associations when a product is deleted.
public void DeleteProductAssociations(int productId)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
string query = "DELETE FROM ProductParts WHERE ProductID = @ProductID";
SQLiteCommand command = new SQLiteCommand(query, conn);
command.Parameters.AddWithValue("@ProductID", productId);
command.ExecuteNonQuery();
}
}
Conclusion
Developing the Inventory Management System in WinForms has been a fantastic learning experience. I was able to implement key features such as data validation, SQLite integration, and robust part-product management. Additionally, handling relationships between parts and products helped me understand the importance of data integrity, especially when dealing with multiple entities.
For anyone embarking on a similar journey, I highly recommend breaking down complex interactions, like part-product associations, into smaller, manageable methods. Also, separating the logic for adding and updating data makes the codebase much cleaner and easier to work with.
I’m excited to continue improving this project and adding new features like advanced search and filtering capabilities. Stay tuned for future updates!
Feel free to check out the project and its source code here.
This project helped me further solidify my understanding of WinForms and database-driven applications. If you’re looking for a solid inventory management system or want to build something similar, I hope this post provides valuable insights into the development process!
Leave a reply