首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# ListView 商品管理範例:新增、合併同項與資料庫刪除

     編輯:關於C語言

功能說明

WinForms 應用示範:從介面輸入商品資訊(名稱、單價、數量),自動計算金額並顯示於 ListView(Details 模式)。若商品名稱已存在,則**合併數量與金額**而非新增行。支援從 ListView 選取並刪除對應資料庫記錄。

介面配置

  • ComboBox comboBox1:商品名稱(可編輯)
  • TextBox textBox1:單價
  • TextBox textBox2:數量
  • Button simpleButton1:新增/合併
  • ListView listView1:View=Details,四欄:商品、單價、數量、金額
  • Button simpleButton2:刪除選取項

核心程式碼

using System;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace ShopDemo {
    public partial class MainForm : Form {
        string connStr = "Server=.;Database=ShopDB;Uid=sa;Pwd=123456;";
        int selectedRow = -1;

        public MainForm() { InitializeComponent(); SetupListView(); }

        void SetupListView() {
            listView1.View = View.Details;
            listView1.FullRowSelect = true;
            listView1.GridLines = true;
            listView1.Columns.Add("商品", 120);
            listView1.Columns.Add("單價", 80);
            listView1.Columns.Add("數量", 80);
            listView1.Columns.Add("金額", 100);
        }

        // 新增/合併按鈕
        private void simpleButton1_Click(object sender, EventArgs e) {
            string goods = comboBox1.Text.Trim();
            string priceText = textBox1.Text.Trim();
            string qtyText = textBox2.Text.Trim();

            if (string.IsNullOrEmpty(goods)) { Msg("商品名稱不能為空"); return; }
            if (string.IsNullOrEmpty(priceText)) { Msg("單價不能為空"); return; }
            if (string.IsNullOrEmpty(qtyText)) { Msg("數量不能為空"); return; }

            if (!decimal.TryParse(priceText, out decimal price) ||
                !int.TryParse(qtyText, out int qty)) {
                Msg("單價或數量格式錯誤"); return;
            }

            decimal amount = price * qty;
            string[] row = { goods, price.ToString("0.##"), qty.ToString(), amount.ToString("0.##") };

            if (TryMergeExisting(row)) return; // 已合併,直接返回

            // 新增列
            var item = new ListViewItem(row);
            listView1.Items.Add(item);
        }

        // 嘗試合併同名商品
        bool TryMergeExisting(string[] row) {
            string goods = row[0];
            int newQty = int.Parse(row[2]);
            decimal newAmt = decimal.Parse(row[3]);

            foreach (ListViewItem item in listView1.Items) {
                if (item.Text == goods) {
                    int oldQty = int.Parse(item.SubItems[2].Text);
                    decimal oldAmt = decimal.Parse(item.SubItems[3].Text);
                    item.SubItems[2].Text = (oldQty + newQty).ToString();
                    item.SubItems[3].Text = (oldAmt + newAmt).ToString("0.##");
                    return true; // 合併完成
                }
            }
            return false;
        }

        // 刪除按鈕
        private void simpleButton2_Click(object sender, EventArgs e) {
            if (listView1.SelectedItems.Count == 0) { Msg("請先選取要刪除的商品"); return; }

            string goods = listView1.SelectedItems[0].Text;
            using (var conn = new SqlConnection(connStr)) {
                conn.Open();
                // 參數化查詢防注入
                string sql = "DELETE FROM Goods WHERE Name = @name";
                using (var cmd = new SqlCommand(sql, conn)) {
                    cmd.Parameters.AddWithValue("@name", goods);
                    int affected = cmd.ExecuteNonQuery();
                    Msg(affected > 0 ? "刪除成功" : "資料庫無此商品");
                }
            }
            // 同步移除 ListView 項目
            listView1.SelectedItems[0].Remove();
        }

        void Msg(string s) => MessageBox.Show(s, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

關鍵技術點

項目說明
ListView 合併邏輯遍歷 Items,比對 Text (第 0 欄),相同則累加 SubItems[2] (數量) 與 SubItems[3] (金額)。
參數化 SQL使用 @name 參數,避免字串拼接導致 SQL 注入。
資料型別轉換decimal.TryParse、int.TryParse 安全轉換,失敗時給予友善提示。
金額格式化ToString("0.##") 保留最多兩位小數,避免顯示多餘尾零。
同步 UI 與 DB資料庫刪除成功後,立即 listView1.SelectedItems[0].Remove() 移除視圖項目。

資料庫表結構 (SQL Server)

CREATE TABLE Goods (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(50) NOT NULL,
    Price DECIMAL(10,2) NOT NULL,
    Qty INT NOT NULL,
    Amount AS Price * Qty PERSISTED
);

常見問題與改進

  • 併發衝突: 多使用者同時修改同一商品,建議加入 RowVersion 或樂觀鎖。
  • 大量資料: ListView 不支援虛擬模式,超過數千筆建議改用 DataGridView + BindingSource。
  • 輸入驗證: 可加入 NumericUpDown 替代數量輸入,限制最小值 1。
  • 例外處理: 資料庫操作應包裹 try/catch (SqlException),記錄日誌並顯示友善錯誤。

完整專案原始碼:GitHub Repository

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved