2010-01-29 41 views
5

Tôi đã rối tung xung quanh với PreviewLostKeyboardFocus mà hầu như giúp bạn ở đó. Tôi đã nhìn thấy một vài triển khai sử dụng LostFocus, nhưng điều đó chỉ tập trung trở lại trên TextBox sau khi nó bị mất tiêu điểm và bạn có thể dễ dàng nhìn thấy sự dịch chuyển này trên màn hình. Về cơ bản, tôi chỉ tìm kiếm cùng một loại hành vi mà bạn có thể nhận được bằng cách sử dụng OnValidating trong WinForms.Cách tốt nhất để tránh mất tiêu điểm TextBox khi có lỗi xác thực là gì?

+1

Bắt lấy nét trong điều khiển có thể dẫn đến trải nghiệm người dùng kém ... Chỉ cần đảm bảo cho phép người dùng thoát khỏi hộp thoại/cửa sổ đó một cách dễ dàng ... –

Trả lời

5

Theo tôi, cách tốt nhất thường không được thực hiện. Nó gần như luôn luôn tốt hơn để chỉ vô hiệu hóa các điều khiển khác hoặc ngăn chặn tiết kiệm cho đến khi giá trị là hợp lệ.

Nhưng nếu thiết kế của bạn thực sự cần khả năng này, đây là những gì bạn nên làm:

  1. Intercept phiên bản Preview của bàn phím và chuột sự kiện ở cấp cửa sổ của bạn, hoặc bất cứ điều gì phạm vi bạn muốn ngăn chặn những thay đổi tập trung bên trong (ví dụ: có thể không phải thanh trình đơn của bạn).

  2. Khi phát hiện phím TabDown hoặc Return KeyDown trong hộp văn bản hoặc khi phát hiện MouseDown bên ngoài hộp văn bản trong khi nó có tiêu điểm, hãy gọi UpdateSource() trên biểu thức ràng buộc, sau đó nếu xác thực không thành công set Handled = true để ngăn sự kiện KeyDown hoặc MouseDown bị xử lý thêm.

  3. Đồng thời tiếp tục xử lý PreviewLostKeyboardFocus để nắm bắt bất kỳ nguyên nhân thay đổi tiêu điểm nào không phải từ bàn phím hoặc chuột hoặc mã khác của bạn không nhận ra.

+0

cách bắt các sự kiện chuột toàn cục (mức cửa sổ)? Nếu chúng ta có một điều khiển container và tập trung nên ở bên trong trình soạn thảo cho đến khi dữ liệu hợp lệ sẽ được thông qua. –

2

Để thêm vào câu trả lời của Ray:

UpdateSource được gọi là như vậy:

BindingExpression be = userTextbox.GetBindingExpression(TextBox.TextProperty); 
be.UpdateSource(); 

Ngoài ra, như một sự thay thế, bạn có thể thiết lập các hộp văn bản ràng buộc để:

UpdateSourceTrigger = "PropertyChanged"; 

Sau đó sẽ gây ra một kiểm tra liên tục, trong khi trước đây sẽ kiểm tra khi cần thiết (performant).

1

Nếu bạn cố gắng tập trung một phần tử bên trong trình xử lý LostFocus của riêng bạn, bạn sẽ phải đối mặt với StackOverflowException, tôi không chắc chắn về nguyên nhân gốc rễ (tôi nghi ngờ loại tập trung bị trả về) nhưng có một cách giải quyết dễ dàng: .

private void TextBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    var element = (sender as TextBox); 
    if (!theTextBoxWasValidated()) 
    { 
     // doing this would cause a StackOverflowException 
     // element.Focus(); 
     var restoreFocus = (System.Threading.ThreadStart)delegate { element.Focus(); }; 
     Dispatcher.BeginInvoke(restoreFocus); 
    } 
} 

Qua Dispatcher.BeginInvoke bạn chắc chắn rằng khôi phục lại sự tập trung không nhận được trong cách của sự mất mát trong sự tiến bộ của tập trung (và tránh những ngoại lệ khó chịu bạn muốn đối mặt khác)

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