如何在KeyPress函数中实现二次输入及count<=3条件下的按键触发
Let's break this down and fix your two technical problems while aligning with your business rules. First, let's restate the core requirements to confirm we're on the same page:
- If input length ≤ 3: Treat it as quantity, prompt for an Item Code next
- If input length > 3: Treat it as Item Code, use the previously entered quantity (or default to 1 if none) to add to the sale list
First, Add State Tracking for Dual Input Flow
To handle the second input (after entering quantity), we need to track whether we're waiting for an Item Code. Add these class-level variables to your form:
// Tracks if we're expecting an Item Code after entering quantity private bool _isAwaitingItemCode = false; // Stores the quantity entered before waiting for Item Code private string _currentQuantity = string.Empty; // Assume this is your DataTable for sale items (should be class-level) private DataTable _saleItemsTable;
Fix 1: Implement Second Input Logic in SearchItem_KeyPress
We'll modify the KeyPress handler to switch between "quantity input mode" and "item code input mode":
private void SearchItem_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) { string userInput = SearchItem.Text.Trim(); // Skip empty inputs if (string.IsNullOrEmpty(userInput)) { SearchItem.Focus(); return; } // Case 1: We're waiting for an Item Code (after entering quantity) if (_isAwaitingItemCode) { // Treat this input as Item Code, use stored quantity ProcessItemCode(userInput, _currentQuantity); // Reset state for next entry _isAwaitingItemCode = false; _currentQuantity = string.Empty; return; } // Case 2: Normal input - check length to decide quantity vs item code int inputLength = userInput.Length; if (inputLength <= 3) { // Treat as quantity: save it, prompt for Item Code _currentQuantity = userInput; SearchItem.Text = string.Empty; SearchItem.PlaceholderText = "Enter Item Code..."; // Optional: add user hint SearchItem.Focus(); _isAwaitingItemCode = true; } else { // Treat as Item Code, use default quantity 1 if none entered before ProcessItemCode(userInput, "1"); } } }
Fix 2: Handle Key Press Logic for count ≤ 3 Scenario
The code above already handles this by checking input length and switching to "awaiting item code" state. Now let's create the ProcessItemCode helper method to handle database lookup and updating the sale list (this cleans up your original code and avoids duplication):
private void ProcessItemCode(string itemCode, string quantity) { // Validate quantity is a valid number if (!int.TryParse(quantity, out int qty)) { MessageBox.Show("Invalid quantity entered! Please enter a number."); SearchItem.Focus(); return; } // Database lookup logic with using statements (auto-closes connections) using (SqlConnection conn = new SqlConnection(myconstring)) { string query = "SELECT ItemCode, ItemDescription, SRate FROM ITEM WHERE ItemCode = @ItemCode"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("@ItemCode", itemCode); conn.Open(); using (SqlDataReader dr = cmd.ExecuteReader()) { if (dr.Read()) { string foundItemCode = dr["ItemCode"].ToString(); string itemDesc = dr["ItemDescription"].ToString(); double rate = Convert.ToDouble(dr["SRate"]); bool itemExists = false; // Check if item is already in the sale list if (_saleItemsTable.Rows.Count > 0) { foreach (DataGridViewRow row in SaleItemList.Rows) { if (!row.IsNewRow && row.Cells[0].Value.ToString() == foundItemCode) { // Update existing item's quantity and amount int currentQty = Convert.ToInt16(row.Cells[2].Value); int newQty = currentQty + qty; row.Cells[2].Value = newQty; row.Cells[4].Value = newQty * rate; itemExists = true; break; } } } // Add new item if not found in the list if (!itemExists) { DataRow newRow = _saleItemsTable.NewRow(); newRow["ItemCode"] = foundItemCode; newRow["ItemDescription"] = itemDesc; newRow["Qty"] = qty; newRow["Rate"] = rate; newRow["Amount"] = qty * rate; _saleItemsTable.Rows.Add(newRow); } // Update total amount display UpdateTotalAmount(); // Reset input field for next entry ClearSearchInput(); } else { MessageBox.Show($"Item Code {itemCode} not found in database!"); ClearSearchInput(); } } } } // Helper method to update total amount private void UpdateTotalAmount() { int total = 0; foreach (DataGridViewRow row in SaleItemList.Rows) { if (!row.IsNewRow && row.Cells[4].Value != null) { total += Convert.ToInt32(row.Cells[4].Value); } } TotalAmount.Text = total.ToString(); } // Helper method to reset search input private void ClearSearchInput() { SearchItem.Text = string.Empty; SearchItem.PlaceholderText = "Enter Quantity or Item Code..."; SearchItem.Focus(); }
Key Improvements & Notes
- State Tracking: The
_isAwaitingItemCodeflag ensures we know exactly how to interpret each user input - Code Cleanup: Extracted repetitive logic into helper methods for readability and maintainability
- Error Handling: Added validation for quantity (ensures it's a number) and checks for missing items in the database
- Removed Redundant Code: Replaced your manual character-count loop with
userInput.Length(no need to iterate through each character!)
Don't forget to initialize your _saleItemsTable on form load:
private void Form_Load(object sender, EventArgs e) { _saleItemsTable = new DataTable(); _saleItemsTable.Columns.Add("ItemCode"); _saleItemsTable.Columns.Add("ItemDescription"); _saleItemsTable.Columns.Add("Qty", typeof(int)); _saleItemsTable.Columns.Add("Rate", typeof(double)); _saleItemsTable.Columns.Add("Amount", typeof(double)); SaleItemList.DataSource = _saleItemsTable; }
内容的提问来源于stack exchange,提问作者Shahzad Zaheer

