2009-07-31 4 views
7

Tôi rất mới với .Net và WPF và có một vấn đề. Mã này là một đoạn mã. Tôi có số TextBox es để nhập ngày. Tôi kiểm tra đầu vào chính xác bằng cách sử dụng các sự kiện GotFocusLostFocus.WPF TextBox.Focus() annoyance

<TextBox Name="sdDay" Width="40" Text="Day" GotFocus="DateDay_GotFocus" LostFocus="DateDay_LostFocus" Padding="5,5,5,5" HorizontalContentAlignment="Center" Focusable="True"/> 
<TextBox Name="sdMonth" Width="50" Text="Month" GotFocus="DateMonth_GotFocus" LostFocus="DateMonth_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/> 
<TextBox Name="sdYear" Width="50" Text="Year" GotFocus="DateYear_GotFocus" LostFocus="DateYear_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/> 

Và mã:

private void DateDay_GotFocus(object sender, RoutedEventArgs e) 
    { 
     if (((TextBox)sender).Text == "Day") 
      ((TextBox)sender).Text = string.Empty; 
    } 

private void DateDay_LostFocus(object sender, RoutedEventArgs e) 
    { 
     if (((TextBox)sender).Text == string.Empty) 
      ((TextBox)sender).Text = "Day"; 
     else 
      CheckForCorrectDateDay((TextBox)sender); 
    } 

private void CheckForCorrectDateDay(TextBox b) 
    { 
     int day = 0; 

     try 
     { 
      day = int.Parse(b.Text); 

      if (day < 0 || day > 31) 
      { 
       MessageBox.Show("Please enter a correct day."); 
       b.Text = string.Empty; 
       b.Focus(); 
      } 
     } 
     catch (FormatException) 
     { 
      MessageBox.Show("Please enter a number.", "Incorrect Input", MessageBoxButton.OK, MessageBoxImage.Warning); 
      b.Text = string.Empty; 
      b.Focus(); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 

Bây giờ những gì tôi muốn nó phải làm là kiểm tra cho đầu vào chính xác, và nếu thất bại, đặt tiêu điểm trở lại bất cứ điều gì TextBox có một mục nhập không chính xác.

Nó không hoạt động. Sau khi tôi nhập một số ngoài phạm vi (hoặc chữ cái), MessageBox sẽ hiển thị nhưng tiêu điểm chuyển sang TextBox tiếp theo để nhập vào tháng đó.

Tôi đang làm gì sai?

Trả lời

14

Kỹ thuật xác thực của bạn ở đây là, thẳng thắn, rất kém. Điều đó nói rằng, tôi tin rằng vấn đề chỉ là WPF đang xử lý các tab sau khi bạn đã tập trung, do đó, nó được thiết lập tập trung trở lại mục tiếp theo trong thứ tự tập trung.

Một cách giải quyết đơn giản sẽ là để gửi một thông điệp riêng biệt mà được xử lý sau khi được thông báo hiện tại:

if (day < 0 || day > 31) 
{ 
    MessageBox.Show("Please enter a correct day."); 
    b.Text = string.Empty; 

    Dispatcher.BeginInvoke((ThreadStart)delegate 
    { 
     b.Focus(); 
    }); 
} 

Việc làm này đảm bảo rằng WPF hoàn toàn quá trình xử lý LostFocus sự kiện trước khi nó xử lý các thông điệp riêng biệt để thiết lập tập trung vào sự kiểm soát sai lầm.

Xét về làm thế nào bạn có thể giải quyết vấn đề này một cách rất đẹp, bạn có thể:

  1. Xác định một mô hình quan điểm với các thuộc tính cho ngày, tháng, và năm (điều kiện tiên quyết: đọc lên trên mô hình MVVM)
  2. Thực hiện IDataErrorInfo trên mô hình xem
  3. Bind các TextBox es trong UI để các thuộc tính tương ứng trên mô hình điểm (điều kiện tiên quyết: đọc lên trên dữ liệu WPF ràng buộc)
+0

Cảm ơn bạn đã trả lời. Tôi hiểu lời giải thích của bạn về vấn đề nhưng không chính xác là giải pháp. Như tôi đã nói, tôi rất mới với .Net. Và tôi sẽ không bận tâm một số mẹo về kỹ thuật xác thực tốt hơn. – Moss

+0

Điều chắc chắn. Đã thêm một số chi tiết khác vào bài đăng của tôi. –

+0

Tôi muốn nhắc lại nhận xét của Kent - buộc việc tập trung trở lại là một cách chắc chắn để làm cho người dùng của bạn tức giận. –