2009-03-05 43 views
7

Cách thanh lịch nhất để hạn chế đầu vào của điều khiển TextBox (hoặc bất kỳ điều gì khác có tiêu chuẩn với .NET 3.5) cho các số dấu phẩy động?Cách tốt nhất để thực hiện các hạn chế đầu vào trên một TextBox trong C# là gì?

Hiện tại, tôi đang tự mình thực hiện tất cả việc nâng hạng nặng bằng cách kế thừa từ TextBox và ghi đè OnKeyPress. Tuy nhiên, tôi không thể không tự hỏi nếu tôi đang phát minh lại bánh xe.

Trả lời

13

Đừng quên các vấn đề/góc-trường hợp sau đây mà bạn sẽ phải đối mặt nếu bạn đi xuống tuyến đường đề xuất của bạn:

  • Người dùng có thể sử dụng tổ hợp phím Ctrl - V hay phím Shift - Chèn để dán các giá trị "không hợp lệ" vào (Thứ hai là một chút phức tạp hơn để bắt) ... nhưng người dùng có thể được phép dán các giá trị pháp lý vào kiểm soát
  • Người dùng có thể nhấp chuột phải, dán các giá trị không hợp lệ trong usi Trình đơn ngữ cảnh mặc định
  • Ngay cả khi bạn đã cố khắc phục vấn đề trước bằng cách đặt hộp văn bản cho menu ngữ cảnh của riêng mình, người dùng có thể nhấp chuột phải ngoài tầm kiểm soát của bạn, giữ nút bên phải, kéo qua hộp văn bản của bạn đi để truy cập mặc định menu ngữ cảnh (và dán vào các giá trị không hợp lệ)
  • Dù chế biến quan trọng bạn không nên vô hiệu hóa tổ hợp phím như Alt - F4, vv (và có, bạn sẽ phá vỡ này nếu bạn đặt SuppressKeyPress cho mọi thứ không phải là chữ số hợp lệ)
  • Người dùng có thể nhập các giá trị một phần (ví dụ:"-.", khi họ bắt đầu gõ "-.23") mà không textbox của bạn trừng phạt chúng
  • số như "-.1e-2" có thể được coi là hợp pháp
  • Một người sử dụng khả thi có thể nhập một giá trị mà chỉ chứa chữ số, nhưng đó sẽ tràn một float
  • Các tồi tệ nhất một trong tất cả: Một số trường hợp góc bí ẩn khác mà người dùng của bạn sẽ tìm thấy sau khi bạn đã giao (!!)

Đạo đức? Nó có thể rất khó khăn để làm những gì bạn đang đề xuất.

Bạn có thể hoặc là muốn làm một sự kết hợp các nội dung sau:

  • Sử dụng một điều khiển mà ai đó mà biết tất cả các trường hợp góc xây dựng (như microsoft)
  • Do xác nhận cơ bản trong trường hợp TextChanged (và làm điều gì đó thụ động, như thay đổi màu nền của hộp văn bản)
  • Lưu xác thực cho đến khi bạn thực sự cố gắng sử dụng giá trị mà họ đã nhập vào
  • Sử dụng thư viện hệ thống để Parse giá trị của người dùng cho bạn
+0

Rất tiếc, rất nhiều trường hợp cần xử lý. Tôi ghét người dùng ...;) –

+0

@ecarF: Không đùa; đó là lý do tại sao nó là một nỗi đau để thực sự xây dựng một điều khiển đầu vào mạnh mẽ như OP đang yêu cầu. –

+0

Yup, đợi người dùng hoàn thành những gì họ đang làm (nhấn OK), sau đó nhấn giá trị lên bằng một regex và tiếp tục hoặc ném một MessageBox. Đẹp hơn nhiều so với OnKeyPress trọng. – Karl

2

Hãy xem kiểm soát MaskedTextBox. Nó cũng được thừa hưởng từ TextBoxBase và có thể có chức năng bạn đang xây dựng trong máy của bạn.

+0

Cảm ơn bạn đã phản hồi nhanh, Mike. Tôi đã làm trong thực tế nghiên cứu kiểm soát MaskedTextBox trước khi sử dụng lao động thủ công, tuy nhiên, tôi không thể làm cho nó hoạt động như tôi muốn ra khỏi hộp với số dấu phẩy động. Có lẽ tôi đã làm một cái gì đó ngu ngốc, mặc dù ... –

+0

Tôi không nghĩ rằng MaskedTextBox có thể làm bất cứ điều gì tốt ở đây, vì nó dường như không cho phép một số lượng vô hạn (người dùng xác định) của nhân vật. –

0

Tôi không nghĩ rằng bánh xe đã được phát minh ra (ít nhất là trong khuôn khổ .NET). Tôi chắc chắn có một cái gì đó trên CodeProject hoặc tương tự, làm tương tự như những gì bạn đang mặc dù, vì vậy nó có thể có giá trị một Google.

Việc nâng hạng nặng không quá quá tệ. Có nhiều hơn một chút so với cái nhìn đầu tiên.

Ví dụ quá đơn giản là bạn có thể xử lý OnKeyPress, thực hiện Float.TryParse với ký tự mới được nối thêm vào. Nếu đúng, hãy giữ phím; nếu sai, hãy hủy nó (e.Handled = true).

Phần khó là nếu họ xóa, cắt hoặc dán lựa chọn. Một điều nữa là khi họ chỉ mới bắt đầu ra (bạn có thể muốn chấp nhận "-" như một phần đầu vào hợp lệ) ...

+0

http://www.codeproject.com/KB/edit/RegexText.aspx dường như làm điều đó. –

+0

Cảm ơn đề xuất của bạn, nhưng nó không đơn giản như vậy. Điều gì sẽ xảy ra nếu người dùng thay đổi vị trí của các ứng dụng? Theo như tôi có thể thấy, bạn không thể mù quáng nối thêm. –

+0

Cảm ơn bạn đã liên kết VirualBlackFox. Tôi chắc chắn sẽ xem xét. –

0

Hoặc kiểm tra xem có phù hợp với sử dụng

void TextBox_KeyUp(object sender, KeyEventArgs e) 
{ 
    if(..) // your condition 
    { 
    e.SuppressKeyPress = false; 
    } 
    else 
    { 
    e.SuppressKeyPress = true; 
    } 
} 

hoặc

void TextBox_KeyUp(object sender, KeyEventArgs e) 
{ 
    e.SuppressKeyPress = CheckInput(e.KeyValue); // where CheckInput is boolean method 
} 
1

Điều gì về việc sử dụng NumericUpDown?

0

tôi phát hiện ra tài sản ValidatingType của một maskedTextBox:

maskedTextBox1.ValidatingType = typeof(System.Double); 

Nó thực sự cho bạn biết cho dù đó là hợp lệ hay không. Thật không may, nó chỉ có vẻ để xác nhận khi tập trung thay đổi (và thậm chí sau đó nó không thực sự làm bất cứ điều gì); nhưng có lẽ có một số cách để sử dụng điều này.

+0

Bạn có thể gọi phương thức "ValidateText" bất cứ khi nào bạn muốn. Vì vậy, để tránh xa các hạn chế thay đổi tập trung, hãy thiết lập một trình xử lý cho TextChanged và nói nếu (maskedTextBox1.MaskCompleted) {maskedTextBox1.ValidateText(); } – CJBrew

0

Có cần phải thực hiện xác thực trong khi nhập dữ liệu hay bạn có thể đủ khả năng kiểm tra giá trị cuối cùng được nhập khi tiêu điểm bị mất không?

Nếu sau này, bạn cũng có thể sử dụng điều khiển ErrorProvider để giúp hạn chế chức năng cho đến khi đầu vào được giải quyết.

+0

Cảm ơn, tôi đoán tôi nên giải thích rõ hơn. Tôi đang xác thực người dùng nhập trong khi nhập dữ liệu. –

Các vấn đề liên quan