我想在 C# 中創建一個表。該表包含兩個列標題。一列標題是產品,另一列標題是產品的價格。我想通過單擊表格中的單元格來輸入資料。我只想在產品價格列的單元格中輸入數字。 有誰知道如何只允許單元格中低于產品價格的數字?

To start, I made one global TextBox variable called CurrentCellBeingEdited. This variable will be set to the currently edited cell. This is used for convenience and is not really necessary, however for this example, it makes things a little clearer.
TextBox CurrentCellBeingEdited = null;
We will assign this variable to the cell the user typed into IF the cell is one of the numeric valued cells. Then we will subscribe (wire-up) the TextBox’s KeyPress event to the proper KeyPress event. This is all done in the grids EditingControlShowing event and may look something like…
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
if (CurrentCellBeingEdited != null) {
CurrentCellBeingEdited.KeyPress -= new KeyPressEventHandler(DecimalNumbersOnlyCell_KeyPress);
CurrentCellBeingEdited.KeyPress -= new KeyPressEventHandler(NumbersOnlyCell_KeyPress);
}
string targetCellColName = dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name;
if (targetCellColName == "Cost" || targetCellColName == "Qty") {
CurrentCellBeingEdited = (TextBox)e.Control;
if (targetCellColName == "Cost") {
CurrentCellBeingEdited.KeyPress = new KeyPressEventHandler(DecimalNumbersOnlyCell_KeyPress);
}
else {
// Qty cell
CurrentCellBeingEdited.KeyPress = new KeyPressEventHandler(NumbersOnlyCell_KeyPress);
}
}
}
This event simply wires up the TextBox cell to the proper key press event if needed. The first if statement…
if (CurrentCellBeingEdited != null) {
CurrentCellBeingEdited.KeyPress -= new KeyPressEventHandler(DecimalNumbersOnlyCell_KeyPress);
CurrentCellBeingEdited.KeyPress -= new KeyPressEventHandler(NumbersOnlyCell_KeyPress);
}
is used to unsubscribe (un-wire) any previously subscribed to event. This prevents the event from firing in the wrong cells. Example; if the user selects the Description cell. And the same idea applies to the Quantity cell where we do not want the user to type a period for a decimal place. The main point is that if we do not “unsubscribe” the text box from the event, then it may get fired multiple times and possibly for the wrong cells.
After any previously enabled event is un-subscribed, the code simply checks which cell is being edited. If the edited cell is a Cost or Quantity column, then the code casts our global variable CurrentCellBeingEdited to the edited cell, then subscribes to the appropriate event.
Next we will need the two KeyPress events for the Cost and Quantity cells and they may look something like…
// Quantity cell
private void NumbersOnlyCell_KeyPress(object sender, KeyPressEventArgs e) {
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) {
e.Handled = true;
}
}
// Cost cell
private void DecimalNumbersOnlyCell_KeyPress(object sender, KeyPressEventArgs e) {
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.') {
e.Handled = true;
}
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1) {
e.Handled = true;
}
}
最后,網格CellValidating事件。請注意,代碼允許單元格為“空”。代碼檢查單元格是否為 Cost 或 Quantity 列,然后將 a 應用于TryParse適當的單元格以驗證單元格中的文本是否確實是有效int或decimal值。如果TryParse失敗,則單元格為紅色,并顯示一個訊息框,指示無效文本。用戶單擊訊息框上的“確定”按鈕后,將取消編輯。
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
if (CurrentCellBeingEdited != null) {
string targetCellColName = dataGridView1.Columns[e.ColumnIndex].Name;
if (targetCellColName == "Cost" || targetCellColName == "Qty") {
if (!string.IsNullOrEmpty(CurrentCellBeingEdited.Text)) { // <- Allow empty cells
bool valid = true;
if (targetCellColName == "Cost") {
if (!decimal.TryParse(CurrentCellBeingEdited.Text, out decimal value)) {
valid = false;
}
}
if (targetCellColName == "Qty") {
if (!int.TryParse(CurrentCellBeingEdited.Text, out int value2)) {
valid = false;
}
}
if (!valid) {
CurrentCellBeingEdited.BackColor = Color.LightCoral;
MessageBox.Show("Invalid input - value will revert to previous amount");
dataGridView1.CancelEdit();
CurrentCellBeingEdited.BackColor = Color.White;
}
}
}
}
}
將所有這些放在一起并完成示例,下面的代碼使用上面的事件來演示此功能。
TextBox CurrentCellBeingEdited = null;
public Form1() {
InitializeComponent();
dataGridView1.CellValidating = new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating);
dataGridView1.EditingControlShowing = new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
private void Form1_Load(object sender, EventArgs e) {
DataTable GridTable = GetDT();
GetData(GridTable);
dataGridView1.DataSource = GridTable;
}
private DataTable GetDT() {
DataTable dt = new DataTable();
dt.Columns.Add("Description", typeof(string));
dt.Columns.Add("Cost", typeof(decimal));
dt.Columns.Add("Qty", typeof(int));
dt.Columns.Add("Total", typeof(decimal), "Cost * Qty");
return dt;
}
private void GetData(DataTable dt) {
dt.Rows.Add("Product1", 12.49, 2);
dt.Rows.Add("Product3", 2.33, 3);
dt.Rows.Add("Product16", 5.00, 12);
}
我希望這是有道理的并有所幫助。
uj5u.com熱心網友回復:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Btn_FillDataGridView_Click(object sender, EventArgs e)
{
var source = new BindingSource();
List<Product> list = new List<Product> { new Product("Shoes",50.14), new Product("T-Shirt", 20.55) };
source.DataSource = list;
DtGrdV_Products.DataSource = source;
}
}
public class Product
{
private string _name;
private double _price;
[DisplayName("Product")]
public string Name { get => _name; set => _name = value; }
[DisplayName("Price of product")]
public double Price { get => _price; set => _price = value; }
public Product(string name, double price)
{
Name = name;
Price = price;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/342661.html
