۱۶
پروژه نهایی: اپلیکیشن مدیریت فروشگاه 🏪
یک اپلیکیشن کامل مدیریت فروشگاه با C# Windows Forms میسازیم!
پیشنمایش پروژه نهایی
در این پروژه، یک اپلیکیشن کامل مدیریت فروشگاه میسازیم که شامل مدیریت محصولات، سیستم فروش، گزارشگیری و اتصال به دیتابیس است.
قابلیتهای اصلی:
- مدیریت کامل محصولات (اضافه، ویرایش، حذف)
- سیستم فروش و صدور فاکتور
- گزارشگیری فروش و موجودی
- اتصال به دیتابیس SQL Server
- رابط کاربری حرفهای با Windows Forms
۱. راهاندازی دیتابیس
ابتدا دیتابیس SQL Server را راهاندازی میکنیم:
Database Script
-- ایجاد دیتابیس
CREATE DATABASE StoreDB;
USE StoreDB;
-- جدول محصولات
CREATE TABLE Products (
Id INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
Category NVARCHAR(50) NOT NULL,
Price DECIMAL(10,2) NOT NULL,
Stock INT NOT NULL DEFAULT 0,
Description NVARCHAR(500),
CreatedDate DATETIME DEFAULT GETDATE()
);
-- جدول فروش
CREATE TABLE Sales (
Id INT IDENTITY(1,1) PRIMARY KEY,
SaleDate DATETIME DEFAULT GETDATE(),
CustomerName NVARCHAR(100),
TotalAmount DECIMAL(10,2) NOT NULL
);
-- جدول جزئیات فروش
CREATE TABLE SaleItems (
Id INT IDENTITY(1,1) PRIMARY KEY,
SaleId INT FOREIGN KEY REFERENCES Sales(Id),
ProductId INT FOREIGN KEY REFERENCES Products(Id),
Quantity INT NOT NULL,
UnitPrice DECIMAL(10,2) NOT NULL,
TotalPrice DECIMAL(10,2) NOT NULL
);
-- دادههای نمونه
INSERT INTO Products (Name, Category, Price, Stock, Description) VALUES
('لپتاپ ایسوس', 'کامپیوتر', 25000000, 5, 'لپتاپ گیمینگ با مشخصات بالا'),
('موس لاجیتک', 'لوازم جانبی', 350000, 20, 'موس بیسیم با کیفیت بالا'),
('کیبورد مکانیکی', 'لوازم جانبی', 1200000, 15, 'کیبورد مکانیکی RGB');
۲. ساختار پروژه و کلاسهای اصلی
کلاسهای اصلی پروژه را تعریف میکنیم:
Models/Product.cs
using System;
namespace StoreManagement.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
public Product()
{
CreatedDate = DateTime.Now;
}
public override string ToString()
{
return $"{Name} - {Price:C} (موجودی: {Stock})";
}
}
}
// Models/Sale.cs
using System;
using System.Collections.Generic;
namespace StoreManagement.Models
{
public class Sale
{
public int Id { get; set; }
public DateTime SaleDate { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
public List Items { get; set; }
public Sale()
{
SaleDate = DateTime.Now;
Items = new List();
}
}
public class SaleItem
{
public int Id { get; set; }
public int SaleId { get; set; }
public int ProductId { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalPrice { get; set; }
}
}
۳. کلاس مدیریت دیتابیس
کلاس کامل برای مدیریت عملیات دیتابیس:
Data/DatabaseHelper.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Windows.Forms;
using StoreManagement.Models;
namespace StoreManagement.Data
{
public class DatabaseHelper
{
private static string connectionString =
"Server=.;Database=StoreDB;Integrated Security=true;";
public static SqlConnection GetConnection()
{
return new SqlConnection(connectionString);
}
// عملیات محصولات
public static List GetAllProducts()
{
List products = new List();
try
{
using (var connection = GetConnection())
{
connection.Open();
string query = "SELECT * FROM Products ORDER BY Name";
using (var command = new SqlCommand(query, connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
products.Add(new Product
{
Id = (int)reader["Id"],
Name = reader["Name"].ToString(),
Category = reader["Category"].ToString(),
Price = (decimal)reader["Price"],
Stock = (int)reader["Stock"],
Description = reader["Description"].ToString(),
CreatedDate = (DateTime)reader["CreatedDate"]
});
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"خطا در بارگیری محصولات: {ex.Message}", "خطا",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return products;
}
public static bool AddProduct(Product product)
{
try
{
using (var connection = GetConnection())
{
connection.Open();
string query = @"INSERT INTO Products (Name, Category, Price, Stock, Description)
VALUES (@Name, @Category, @Price, @Stock, @Description)";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Name", product.Name);
command.Parameters.AddWithValue("@Category", product.Category);
command.Parameters.AddWithValue("@Price", product.Price);
command.Parameters.AddWithValue("@Stock", product.Stock);
command.Parameters.AddWithValue("@Description", product.Description ?? "");
return command.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"خطا در افزودن محصول: {ex.Message}", "خطا",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
public static bool UpdateProduct(Product product)
{
try
{
using (var connection = GetConnection())
{
connection.Open();
string query = @"UPDATE Products SET Name=@Name, Category=@Category,
Price=@Price, Stock=@Stock, Description=@Description
WHERE Id=@Id";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", product.Id);
command.Parameters.AddWithValue("@Name", product.Name);
command.Parameters.AddWithValue("@Category", product.Category);
command.Parameters.AddWithValue("@Price", product.Price);
command.Parameters.AddWithValue("@Stock", product.Stock);
command.Parameters.AddWithValue("@Description", product.Description ?? "");
return command.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"خطا در ویرایش محصول: {ex.Message}", "خطا",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
public static bool DeleteProduct(int productId)
{
try
{
using (var connection = GetConnection())
{
connection.Open();
string query = "DELETE FROM Products WHERE Id=@Id";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", productId);
return command.ExecuteNonQuery() > 0;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"خطا در حذف محصول: {ex.Message}", "خطا",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
}
}
۴. فرم اصلی
فرم اصلی با منوی کامل و Dashboard:
Forms/MainForm.cs
using System;
using System.Drawing;
using System.Windows.Forms;
using StoreManagement.Forms;
namespace StoreManagement
{
public partial class MainForm : Form
{
private Panel dashboardPanel;
private StatusStrip statusStrip;
public MainForm()
{
InitializeComponent();
SetupMainForm();
CreateDashboard();
}
private void SetupMainForm()
{
this.Text = "سیستم مدیریت فروشگاه - نسخه 1.0";
this.Size = new Size(1200, 800);
this.StartPosition = FormStartPosition.CenterScreen;
this.WindowState = FormWindowState.Maximized;
this.Icon = SystemIcons.Application;
// ایجاد منوی اصلی
MenuStrip mainMenu = new MenuStrip();
mainMenu.Font = new Font("Tahoma", 10F);
// منوی محصولات
ToolStripMenuItem productsMenu = new ToolStripMenuItem("محصولات");
productsMenu.DropDownItems.Add("مدیریت محصولات", null, OpenProductsForm);
productsMenu.DropDownItems.Add("افزودن محصول جدید", null, AddNewProduct);
productsMenu.DropDownItems.Add("-");
productsMenu.DropDownItems.Add("دستهبندی محصولات", null, ManageCategories);
// منوی فروش
ToolStripMenuItem salesMenu = new ToolStripMenuItem("فروش");
salesMenu.DropDownItems.Add("فروش جدید", null, OpenSalesForm);
salesMenu.DropDownItems.Add("تاریخچه فروش", null, OpenSalesHistory);
salesMenu.DropDownItems.Add("-");
salesMenu.DropDownItems.Add("مرجوعی کالا", null, ProcessReturn);
// منوی گزارشات
ToolStripMenuItem reportsMenu = new ToolStripMenuItem("گزارشات");
reportsMenu.DropDownItems.Add("گزارش فروش روزانه", null, DailySalesReport);
reportsMenu.DropDownItems.Add("گزارش موجودی", null, InventoryReport);
reportsMenu.DropDownItems.Add("گزارش سود و زیان", null, ProfitLossReport);
reportsMenu.DropDownItems.Add("-");
reportsMenu.DropDownItems.Add("چاپ گزارش", null, PrintReport);
// منوی تنظیمات
ToolStripMenuItem settingsMenu = new ToolStripMenuItem("تنظیمات");
settingsMenu.DropDownItems.Add("تنظیمات عمومی", null, OpenSettings);
settingsMenu.DropDownItems.Add("پشتیبانگیری", null, BackupDatabase);
settingsMenu.DropDownItems.Add("-");
settingsMenu.DropDownItems.Add("درباره برنامه", null, ShowAbout);
mainMenu.Items.AddRange(new ToolStripItem[] {
productsMenu, salesMenu, reportsMenu, settingsMenu
});
this.MainMenuStrip = mainMenu;
this.Controls.Add(mainMenu);
// ایجاد نوار وضعیت
statusStrip = new StatusStrip();
statusStrip.Items.Add(new ToolStripStatusLabel("آماده"));
statusStrip.Items.Add(new ToolStripStatusLabel($"تاریخ: {DateTime.Now.ToShortDateString()}"));
this.Controls.Add(statusStrip);
}
private void CreateDashboard()
{
dashboardPanel = new Panel()
{
Dock = DockStyle.Fill,
BackColor = Color.WhiteSmoke
};
// عنوان Dashboard
Label titleLabel = new Label()
{
Text = "داشبورد مدیریت فروشگاه",
Font = new Font("Tahoma", 16F, FontStyle.Bold),
Location = new Point(50, 50),
Size = new Size(400, 30),
ForeColor = Color.DarkBlue
};
// کارتهای اطلاعاتی
CreateInfoCard("تعداد محصولات", "125", Color.Blue, new Point(50, 100));
CreateInfoCard("فروش امروز", "2,500,000 تومان", Color.Green, new Point(300, 100));
CreateInfoCard("موجودی کم", "8 محصول", Color.Orange, new Point(550, 100));
CreateInfoCard("سود خالص", "750,000 تومان", Color.Purple, new Point(800, 100));
dashboardPanel.Controls.Add(titleLabel);
this.Controls.Add(dashboardPanel);
}
private void CreateInfoCard(string title, string value, Color color, Point location)
{
Panel card = new Panel()
{
Size = new Size(200, 120),
Location = location,
BackColor = Color.White,
BorderStyle = BorderStyle.FixedSingle
};
Label titleLabel = new Label()
{
Text = title,
Font = new Font("Tahoma", 10F),
Location = new Point(10, 10),
Size = new Size(180, 20),
TextAlign = ContentAlignment.MiddleCenter
};
Label valueLabel = new Label()
{
Text = value,
Font = new Font("Tahoma", 14F, FontStyle.Bold),
ForeColor = color,
Location = new Point(10, 40),
Size = new Size(180, 60),
TextAlign = ContentAlignment.MiddleCenter
};
card.Controls.AddRange(new Control[] { titleLabel, valueLabel });
dashboardPanel.Controls.Add(card);
}
// Event Handlers
private void OpenProductsForm(object sender, EventArgs e)
{
ProductsForm productsForm = new ProductsForm();
productsForm.ShowDialog();
}
private void AddNewProduct(object sender, EventArgs e)
{
AddEditProductForm addForm = new AddEditProductForm();
addForm.ShowDialog();
}
private void OpenSalesForm(object sender, EventArgs e)
{
SalesForm salesForm = new SalesForm();
salesForm.ShowDialog();
}
private void OpenSalesHistory(object sender, EventArgs e)
{
SalesHistoryForm historyForm = new SalesHistoryForm();
historyForm.ShowDialog();
}
private void ManageCategories(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void ProcessReturn(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void DailySalesReport(object sender, EventArgs e)
{
ReportsForm reportsForm = new ReportsForm();
reportsForm.ShowDialog();
}
private void InventoryReport(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void ProfitLossReport(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void PrintReport(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void OpenSettings(object sender, EventArgs e)
{
MessageBox.Show("این قابلیت در نسخههای بعدی اضافه خواهد شد.", "اطلاع");
}
private void BackupDatabase(object sender, EventArgs e)
{
MessageBox.Show("پشتیبانگیری با موفقیت انجام شد.", "موفقیت");
}
private void ShowAbout(object sender, EventArgs e)
{
MessageBox.Show("سیستم مدیریت فروشگاه\nنسخه 1.0\nتوسعه یافته با C# Windows Forms",
"درباره برنامه");
}
}
}
۵. فرم مدیریت محصولات
فرم کامل برای مدیریت محصولات با DataGridView:
Forms/ProductsForm.cs
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using StoreManagement.Data;
using StoreManagement.Models;
namespace StoreManagement.Forms
{
public partial class ProductsForm : Form
{
private DataGridView productsGrid;
private TextBox searchBox;
private ComboBox categoryFilter;
private Button addButton, editButton, deleteButton, refreshButton;
public ProductsForm()
{
InitializeComponent();
SetupForm();
LoadProducts();
}
private void SetupForm()
{
this.Text = "مدیریت محصولات";
this.Size = new Size(1000, 600);
this.StartPosition = FormStartPosition.CenterParent;
// پنل بالا برای جستجو و فیلتر
Panel topPanel = new Panel()
{
Height = 60,
Dock = DockStyle.Top,
BackColor = Color.LightGray
};
// جعبه جستجو
Label searchLabel = new Label()
{
Text = "جستجو:",
Location = new Point(10, 20),
Size = new Size(50, 20)
};
searchBox = new TextBox()
{
Location = new Point(70, 18),
Size = new Size(200, 20)
};
searchBox.TextChanged += SearchBox_TextChanged;
// فیلتر دستهبندی
Label categoryLabel = new Label()
{
Text = "دستهبندی:",
Location = new Point(290, 20),
Size = new Size(70, 20)
};
categoryFilter = new ComboBox()
{
Location = new Point(370, 18),
Size = new Size(150, 20),
DropDownStyle = ComboBoxStyle.DropDownList
};
categoryFilter.Items.AddRange(new[] { "همه", "کامپیوتر", "لوازم جانبی", "موبایل" });
categoryFilter.SelectedIndex = 0;
categoryFilter.SelectedIndexChanged += CategoryFilter_SelectedIndexChanged;
topPanel.Controls.AddRange(new Control[] {
searchLabel, searchBox, categoryLabel, categoryFilter
});
// پنل پایین برای دکمهها
Panel bottomPanel = new Panel()
{
Height = 60,
Dock = DockStyle.Bottom,
BackColor = Color.LightGray
};
addButton = new Button()
{
Text = "افزودن محصول",
Location = new Point(10, 15),
Size = new Size(100, 30),
BackColor = Color.Green,
ForeColor = Color.White
};
addButton.Click += AddButton_Click;
editButton = new Button()
{
Text = "ویرایش",
Location = new Point(120, 15),
Size = new Size(80, 30),
BackColor = Color.Orange,
ForeColor = Color.White
};
editButton.Click += EditButton_Click;
deleteButton = new Button()
{
Text = "حذف",
Location = new Point(210, 15),
Size = new Size(80, 30),
BackColor = Color.Red,
ForeColor = Color.White
};
deleteButton.Click += DeleteButton_Click;
refreshButton = new Button()
{
Text = "بروزرسانی",
Location = new Point(300, 15),
Size = new Size(80, 30),
BackColor = Color.Blue,
ForeColor = Color.White
};
refreshButton.Click += RefreshButton_Click;
bottomPanel.Controls.AddRange(new Control[] {
addButton, editButton, deleteButton, refreshButton
});
// DataGridView
productsGrid = new DataGridView()
{
Dock = DockStyle.Fill,
AutoGenerateColumns = false,
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
MultiSelect = false,
ReadOnly = true,
AllowUserToAddRows = false,
AllowUserToDeleteRows = false
};
// تعریف ستونها
productsGrid.Columns.AddRange(new DataGridViewColumn[]
{
new DataGridViewTextBoxColumn { Name = "Id", HeaderText = "شناسه", DataPropertyName = "Id", Width = 60 },
new DataGridViewTextBoxColumn { Name = "Name", HeaderText = "نام محصول", DataPropertyName = "Name", Width = 200 },
new DataGridViewTextBoxColumn { Name = "Category", HeaderText = "دستهبندی", DataPropertyName = "Category", Width = 120 },
new DataGridViewTextBoxColumn { Name = "Price", HeaderText = "قیمت", DataPropertyName = "Price", Width = 100 },
new DataGridViewTextBoxColumn { Name = "Stock", HeaderText = "موجودی", DataPropertyName = "Stock", Width = 80 },
new DataGridViewTextBoxColumn { Name = "Description", HeaderText = "توضیحات", DataPropertyName = "Description", Width = 250 }
});
this.Controls.AddRange(new Control[] { productsGrid, topPanel, bottomPanel });
}
private void LoadProducts()
{
var products = DatabaseHelper.GetAllProducts();
productsGrid.DataSource = products;
}
private void SearchBox_TextChanged(object sender, EventArgs e)
{
FilterProducts();
}
private void CategoryFilter_SelectedIndexChanged(object sender, EventArgs e)
{
FilterProducts();
}
private void FilterProducts()
{
var allProducts = DatabaseHelper.GetAllProducts();
var filteredProducts = allProducts.AsEnumerable();
// فیلتر بر اساس جستجو
if (!string.IsNullOrEmpty(searchBox.Text))
{
filteredProducts = filteredProducts.Where(p =>
p.Name.Contains(searchBox.Text) ||
p.Description.Contains(searchBox.Text));
}
// فیلتر بر اساس دستهبندی
if (categoryFilter.SelectedIndex > 0)
{
string selectedCategory = categoryFilter.SelectedItem.ToString();
filteredProducts = filteredProducts.Where(p => p.Category == selectedCategory);
}
productsGrid.DataSource = filteredProducts.ToList();
}
private void AddButton_Click(object sender, EventArgs e)
{
AddEditProductForm addForm = new AddEditProductForm();
if (addForm.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
private void EditButton_Click(object sender, EventArgs e)
{
if (productsGrid.SelectedRows.Count > 0)
{
var selectedProduct = (Product)productsGrid.SelectedRows[0].DataBoundItem;
AddEditProductForm editForm = new AddEditProductForm(selectedProduct);
if (editForm.ShowDialog() == DialogResult.OK)
{
LoadProducts();
}
}
else
{
MessageBox.Show("لطفاً یک محصول را انتخاب کنید.", "هشدار");
}
}
private void DeleteButton_Click(object sender, EventArgs e)
{
if (productsGrid.SelectedRows.Count > 0)
{
var selectedProduct = (Product)productsGrid.SelectedRows[0].DataBoundItem;
var result = MessageBox.Show($"آیا از حذف محصول '{selectedProduct.Name}' اطمینان دارید؟",
"تأیید حذف", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
if (DatabaseHelper.DeleteProduct(selectedProduct.Id))
{
MessageBox.Show("محصول با موفقیت حذف شد.", "موفقیت");
LoadProducts();
}
}
}
else
{
MessageBox.Show("لطفاً یک محصول را انتخاب کنید.", "هشدار");
}
}
private void RefreshButton_Click(object sender, EventArgs e)
{
LoadProducts();
}
}
}
۶. فرم افزودن/ویرایش محصول
فرم کامل برای افزودن و ویرایش محصولات:
Forms/AddEditProductForm.cs
using System;
using System.Drawing;
using System.Windows.Forms;
using StoreManagement.Data;
using StoreManagement.Models;
namespace StoreManagement.Forms
{
public partial class AddEditProductForm : Form
{
private Product currentProduct;
private bool isEditMode;
private TextBox nameTextBox, priceTextBox, stockTextBox, descriptionTextBox;
private ComboBox categoryComboBox;
private Button saveButton, cancelButton;
public AddEditProductForm(Product product = null)
{
currentProduct = product;
isEditMode = product != null;
InitializeComponent();
SetupForm();
if (isEditMode)
{
LoadProductData();
}
}
private void SetupForm()
{
this.Text = isEditMode ? "ویرایش محصول" : "افزودن محصول جدید";
this.Size = new Size(450, 400);
this.StartPosition = FormStartPosition.CenterParent;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
// نام محصول
Label nameLabel = new Label()
{
Text = "نام محصول:",
Location = new Point(20, 30),
Size = new Size(80, 20)
};
nameTextBox = new TextBox()
{
Location = new Point(110, 28),
Size = new Size(300, 20)
};
// دستهبندی
Label categoryLabel = new Label()
{
Text = "دستهبندی:",
Location = new Point(20, 70),
Size = new Size(80, 20)
};
categoryComboBox = new ComboBox()
{
Location = new Point(110, 68),
Size = new Size(200, 20),
DropDownStyle = ComboBoxStyle.DropDownList
};
categoryComboBox.Items.AddRange(new[] { "کامپیوتر", "لوازم جانبی", "موبایل", "تبلت" });
// قیمت
Label priceLabel = new Label()
{
Text = "قیمت (تومان):",
Location = new Point(20, 110),
Size = new Size(80, 20)
};
priceTextBox = new TextBox()
{
Location = new Point(110, 108),
Size = new Size(150, 20)
};
// موجودی
Label stockLabel = new Label()
{
Text = "موجودی:",
Location = new Point(20, 150),
Size = new Size(80, 20)
};
stockTextBox = new TextBox()
{
Location = new Point(110, 148),
Size = new Size(100, 20)
};
// توضیحات
Label descriptionLabel = new Label()
{
Text = "توضیحات:",
Location = new Point(20, 190),
Size = new Size(80, 20)
};
descriptionTextBox = new TextBox()
{
Location = new Point(110, 188),
Size = new Size(300, 80),
Multiline = true,
ScrollBars = ScrollBars.Vertical
};
// دکمهها
saveButton = new Button()
{
Text = "ذخیره",
Location = new Point(220, 300),
Size = new Size(80, 30),
BackColor = Color.Green,
ForeColor = Color.White,
DialogResult = DialogResult.OK
};
saveButton.Click += SaveButton_Click;
cancelButton = new Button()
{
Text = "انصراف",
Location = new Point(310, 300),
Size = new Size(80, 30),
BackColor = Color.Gray,
ForeColor = Color.White,
DialogResult = DialogResult.Cancel
};
this.Controls.AddRange(new Control[] {
nameLabel, nameTextBox,
categoryLabel, categoryComboBox,
priceLabel, priceTextBox,
stockLabel, stockTextBox,
descriptionLabel, descriptionTextBox,
saveButton, cancelButton
});
}
private void LoadProductData()
{
if (currentProduct != null)
{
nameTextBox.Text = currentProduct.Name;
categoryComboBox.Text = currentProduct.Category;
priceTextBox.Text = currentProduct.Price.ToString();
stockTextBox.Text = currentProduct.Stock.ToString();
descriptionTextBox.Text = currentProduct.Description;
}
}
private void SaveButton_Click(object sender, EventArgs e)
{
if (ValidateInput())
{
var product = new Product()
{
Name = nameTextBox.Text.Trim(),
Category = categoryComboBox.Text,
Price = decimal.Parse(priceTextBox.Text),
Stock = int.Parse(stockTextBox.Text),
Description = descriptionTextBox.Text.Trim()
};
bool success;
if (isEditMode)
{
product.Id = currentProduct.Id;
success = DatabaseHelper.UpdateProduct(product);
}
else
{
success = DatabaseHelper.AddProduct(product);
}
if (success)
{
MessageBox.Show(isEditMode ? "محصول با موفقیت ویرایش شد." : "محصول با موفقیت اضافه شد.",
"موفقیت", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
this.DialogResult = DialogResult.None;
}
}
else
{
this.DialogResult = DialogResult.None;
}
}
private bool ValidateInput()
{
if (string.IsNullOrWhiteSpace(nameTextBox.Text))
{
MessageBox.Show("نام محصول را وارد کنید.", "خطا");
nameTextBox.Focus();
return false;
}
if (categoryComboBox.SelectedIndex == -1)
{
MessageBox.Show("دستهبندی را انتخاب کنید.", "خطا");
categoryComboBox.Focus();
return false;
}
if (!decimal.TryParse(priceTextBox.Text, out decimal price) || price <= 0)
{
MessageBox.Show("قیمت معتبر وارد کنید.", "خطا");
priceTextBox.Focus();
return false;
}
if (!int.TryParse(stockTextBox.Text, out int stock) || stock < 0)
{
MessageBox.Show("موجودی معتبر وارد کنید.", "خطا");
stockTextBox.Focus();
return false;
}
return true;
}
}
}
۷. فرم فروش
فرم کامل برای ثبت فروش جدید:
Forms/SalesForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using StoreManagement.Data;
using StoreManagement.Models;
namespace StoreManagement.Forms
{
public partial class SalesForm : Form
{
private TextBox customerNameTextBox;
private ComboBox productComboBox;
private NumericUpDown quantityNumeric;
private DataGridView salesItemsGrid;
private Label totalLabel;
private Button addItemButton, removeItemButton, completeSaleButton;
private List saleItems;
private List availableProducts;
public SalesForm()
{
saleItems = new List();
InitializeComponent();
SetupForm();
LoadProducts();
}
private void SetupForm()
{
this.Text = "فروش جدید";
this.Size = new Size(800, 600);
this.StartPosition = FormStartPosition.CenterParent;
// اطلاعات مشتری
GroupBox customerGroup = new GroupBox()
{
Text = "اطلاعات مشتری",
Location = new Point(10, 10),
Size = new Size(760, 60)
};
Label customerLabel = new Label()
{
Text = "نام مشتری:",
Location = new Point(10, 25),
Size = new Size(80, 20)
};
customerNameTextBox = new TextBox()
{
Location = new Point(100, 23),
Size = new Size(200, 20)
};
customerGroup.Controls.AddRange(new Control[] { customerLabel, customerNameTextBox });
// افزودن محصول
GroupBox productGroup = new GroupBox()
{
Text = "افزودن محصول",
Location = new Point(10, 80),
Size = new Size(760, 80)
};
Label productLabel = new Label()
{
Text = "محصول:",
Location = new Point(10, 25),
Size = new Size(60, 20)
};
productComboBox = new ComboBox()
{
Location = new Point(80, 23),
Size = new Size(250, 20),
DropDownStyle = ComboBoxStyle.DropDownList
};
Label quantityLabel = new Label()
{
Text = "تعداد:",
Location = new Point(350, 25),
Size = new Size(50, 20)
};
quantityNumeric = new NumericUpDown()
{
Location = new Point(410, 23),
Size = new Size(80, 20),
Minimum = 1,
Maximum = 1000,
Value = 1
};
addItemButton = new Button()
{
Text = "افزودن",
Location = new Point(510, 22),
Size = new Size(80, 25),
BackColor = Color.Green,
ForeColor = Color.White
};
addItemButton.Click += AddItemButton_Click;
productGroup.Controls.AddRange(new Control[] {
productLabel, productComboBox, quantityLabel, quantityNumeric, addItemButton
});
// لیست اقلام فروش
GroupBox itemsGroup = new GroupBox()
{
Text = "اقلام فروش",
Location = new Point(10, 170),
Size = new Size(760, 300)
};
salesItemsGrid = new DataGridView()
{
Location = new Point(10, 20),
Size = new Size(740, 240),
AutoGenerateColumns = false,
SelectionMode = DataGridViewSelectionMode.FullRowSelect,
AllowUserToAddRows = false
};
salesItemsGrid.Columns.AddRange(new DataGridViewColumn[]
{
new DataGridViewTextBoxColumn { Name = "ProductName", HeaderText = "نام محصول", DataPropertyName = "ProductName", Width = 200 },
new DataGridViewTextBoxColumn { Name = "Quantity", HeaderText = "تعداد", DataPropertyName = "Quantity", Width = 80 },
new DataGridViewTextBoxColumn { Name = "UnitPrice", HeaderText = "قیمت واحد", DataPropertyName = "UnitPrice", Width = 120 },
new DataGridViewTextBoxColumn { Name = "TotalPrice", HeaderText = "قیمت کل", DataPropertyName = "TotalPrice", Width = 120 }
});
removeItemButton = new Button()
{
Text = "حذف آیتم",
Location = new Point(10, 270),
Size = new Size(80, 25),
BackColor = Color.Red,
ForeColor = Color.White
};
removeItemButton.Click += RemoveItemButton_Click;
itemsGroup.Controls.AddRange(new Control[] { salesItemsGrid, removeItemButton });
// مجموع و تکمیل فروش
totalLabel = new Label()
{
Text = "مجموع: 0 تومان",
Location = new Point(500, 490),
Size = new Size(150, 20),
Font = new Font("Tahoma", 12F, FontStyle.Bold),
ForeColor = Color.Blue
};
completeSaleButton = new Button()
{
Text = "تکمیل فروش",
Location = new Point(670, 485),
Size = new Size(100, 30),
BackColor = Color.Blue,
ForeColor = Color.White,
Font = new Font("Tahoma", 10F, FontStyle.Bold)
};
completeSaleButton.Click += CompleteSaleButton_Click;
this.Controls.AddRange(new Control[] {
customerGroup, productGroup, itemsGroup, totalLabel, completeSaleButton
});
}
private void LoadProducts()
{
availableProducts = DatabaseHelper.GetAllProducts().Where(p => p.Stock > 0).ToList();
productComboBox.DataSource = availableProducts;
productComboBox.DisplayMember = "Name";
productComboBox.ValueMember = "Id";
}
private void AddItemButton_Click(object sender, EventArgs e)
{
if (productComboBox.SelectedItem is Product selectedProduct)
{
int quantity = (int)quantityNumeric.Value;
if (quantity > selectedProduct.Stock)
{
MessageBox.Show($"موجودی کافی نیست. موجودی فعلی: {selectedProduct.Stock}", "خطا");
return;
}
// بررسی اینکه آیا محصول قبلاً اضافه شده
var existingItem = saleItems.FirstOrDefault(item => item.ProductId == selectedProduct.Id);
if (existingItem != null)
{
existingItem.Quantity += quantity;
existingItem.TotalPrice = existingItem.Quantity * existingItem.UnitPrice;
}
else
{
saleItems.Add(new SaleItem
{
ProductId = selectedProduct.Id,
ProductName = selectedProduct.Name,
Quantity = quantity,
UnitPrice = selectedProduct.Price,
TotalPrice = quantity * selectedProduct.Price
});
}
RefreshSalesGrid();
UpdateTotal();
}
}
private void RemoveItemButton_Click(object sender, EventArgs e)
{
if (salesItemsGrid.SelectedRows.Count > 0)
{
var selectedItem = (SaleItem)salesItemsGrid.SelectedRows[0].DataBoundItem;
saleItems.Remove(selectedItem);
RefreshSalesGrid();
UpdateTotal();
}
}
private void RefreshSalesGrid()
{
salesItemsGrid.DataSource = null;
salesItemsGrid.DataSource = saleItems;
}
private void UpdateTotal()
{
decimal total = saleItems.Sum(item => item.TotalPrice);
totalLabel.Text = $"مجموع: {total:N0} تومان";
}
private void CompleteSaleButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(customerNameTextBox.Text))
{
MessageBox.Show("نام مشتری را وارد کنید.", "خطا");
return;
}
if (saleItems.Count == 0)
{
MessageBox.Show("حداقل یک محصول اضافه کنید.", "خطا");
return;
}
// ایجاد فروش جدید
var sale = new Sale
{
CustomerName = customerNameTextBox.Text.Trim(),
TotalAmount = saleItems.Sum(item => item.TotalPrice),
Items = saleItems
};
// ذخیره فروش در دیتابیس (این بخش باید در DatabaseHelper پیادهسازی شود)
MessageBox.Show($"فروش با موفقیت ثبت شد.\nمجموع: {sale.TotalAmount:N0} تومان", "موفقیت");
// پاک کردن فرم
ClearForm();
}
private void ClearForm()
{
customerNameTextBox.Clear();
saleItems.Clear();
RefreshSalesGrid();
UpdateTotal();
LoadProducts();
}
}
}
۸. نکات پیادهسازی و بهبود
🔧 بهبودهای پیشنهادی:
- اضافه کردن Validation بیشتر برای ورودیها
- پیادهسازی سیستم لاگ برای ردیابی عملیات
- اضافه کردن قابلیت چاپ فاکتور
- پیادهسازی سیستم بکآپ خودکار
- اضافه کردن گزارشات تحلیلی
📊 قابلیتهای اضافی:
- مدیریت کاربران و سطوح دسترسی
- سیستم تخفیف و کوپن
- مدیریت تأمینکنندگان
- سیستم هشدار موجودی کم
- اتصال به بارکد اسکنر
🎨 بهبود رابط کاربری:
- استفاده از تمهای مدرن
- اضافه کردن آیکونها و تصاویر
- پیادهسازی انیمیشنهای ساده
- بهبود تجربه کاربری با کیبورد شورتکات
- پشتیبانی از چند زبانه
آفرین! دوره تموم شد! 🥳
شما با موفقیت این دوره کامل C# Windows Forms رو به پایان رسوندین و یک اپلیکیشن واقعی مدیریت فروشگاه ساختین! حالا یه درک عمیق از برنامهنویسی دسکتاپ با C# دارین و آمادهاین که وارد دنیای WPF، ASP.NET یا Xamarin بشین. موفق باشی!