2010-02-26 31 views
5

sử dụng C# winforms vs2008Làm thế nào để dừng việc hủy sự kiện hộp văn bản trên biểu mẫu đóng

Tôi có một hộp văn bản trên biểu mẫu có phương thức được gọi từ sự kiện textBox1_Leave. Phương thức này lấy nội dung của hộp văn bản được đề cập và điền vào các hộp văn bản khác dựa trên nội dung. Vấn đề của tôi là người dùng đã tập trung vào hộp văn bản sau đó nhấp vào nút để đóng biểu mẫu (gọi this.close), sau đó biểu mẫu không đóng vì sự kiện rời khỏi hộp văn bản được kích hoạt. Nếu hộp văn bản không tập trung vào biểu mẫu đóng thì biểu mẫu sẽ đóng lại.

Nếu tuy nhiên người dùng đóng biểu mẫu bằng cách nhấp vào biểu tượng X nhỏ ở góc trên cùng, nó sẽ luôn luôn hoạt động tốt khi sự kiện rời khỏi hộp văn bản được kích hoạt.

Làm cách nào để sao chép chức năng đóng X để tôi luôn có thể đóng biểu mẫu mà không cần sự kiện rời khỏi hộp văn bản được kích hoạt?

+0

này hoạt động tuyệt vời đối với tôi. http://stackoverflow.com/questions/2664639/cancel-leave-event-when-closing –

Trả lời

7

Giải pháp đơn giản nhất sẽ là để kiểm tra kiểm soát thực sự tập trung trước khi làm post-processing của bạn - nhưng bạn không thể làm điều đó trong xử lý Leave, vì trọng tâm vẫn sẽ được vào hộp văn bản tại thời điểm đó.

Thay vào đó, bạn cần di chuyển logic của mình đến sự kiện LostFocus, không có trong nhà thiết kế. Bạn sẽ phải dây nó lên trong thời gian chạy:

public class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     textBox1.LostFocus += new EventHandler(textBox1_LostFocus); 
    } 

    private void textBox1_LostFocus(object sender, EventArgs e) 
    { 
     if (closeButton.Focused) 
      return; 
     // Update the other text boxes here 
    } 
} 

Sự kiện LostFocus xảy ra để bắn sau điều khiển mới nhận được tập trung.

Làm rõ - bạn có thể thấy rằng nó hoạt động bằng cách đặt logic này trong trường hợp Leave - nếu tập trung được thay đổi bằng cách chuột. Nếu bàn phím được sử dụng thay vào đó, bạn sẽ nhận được hành vi sai. LostFocus đáng tin cậy trong cả hai trường hợp - điều khiển tập trung sẽ luôn là là điều khiển "mới". Đây là tài liệu trên MSDN: Order of Events in Windows Forms.

Ngẫu nhiên, lý do tại sao bạn không gặp vấn đề này với "X đỏ" là X không thực sự là một điều khiển có thể nhận tiêu điểm, đó là một phần của cửa sổ. Khi người dùng nhấp vào đó, nó sẽ không làm cho hộp văn bản mất tiêu điểm và do đó không gây ra sự kiện Leave để kích hoạt.

+0

Tôi không đồng ý với nhận xét về 'Để lại hành vi không chính xác, hãy xem - http://msdn.microsoft.com/en-us/library/system.windows.forms.control.leave.aspx (tình cờ tham số tập trung được thay đổi trước khi điều khiển nhận được gọi 'Enter', xuất hiện đầu tiên theo thứ tự sự kiện) –

+0

Tùy thuộc vào chức năng cần thiết, có thể có vấn đề với cách tiếp cận này. Nếu nút đóng tiếp theo trong thứ tự tab sau hộp văn bản và người dùng nhấn TAB để rời khỏi hộp văn bản, điều này sẽ giữ cho các bản cập nhật bạn muốn xảy ra, mặc dù chúng phải như vậy. –

+0

Hãy suy nghĩ theo cách này và xem nó như thế nào cảm ơn tất cả mọi người vì đã nhập – Spooky2010

0

bạn có thể kiểm tra xem điều khiển nào vừa được lấy nét.

private void textBox1_Leave(object sender, EventArgs e) 
{ 
    if (btnClose.Focused) 
     return; 
    // go from here 
} 
+0

Bạn đang đóng - nhưng tiêu điểm chưa thay đổi trong sự kiện 'Rời khỏi '. – Aaronaught

2

Cách tiếp cận khác: Sử dụng sự kiện xác thực của hộp văn bản thay vì sự kiện rời khỏi sự kiện, sau đó thay đổi thuộc tính CausesValidation của nút thành false. Bạn cũng sẽ phải đặt hộp văn bản không gây ra xác thực trong sự kiện nhấp của nút để sự kiện xác thực sẽ không kích hoạt khi biểu mẫu đóng (nhờ @Powerlord chỉ ra điều này).

private void button1_Click(object sender, EventArgs e) 
{ 
    this.textBox1.CausesValidation = false; 
    this.Close(); 
} 
1

Bạn cũng có thể xử lý sự kiện FormClosing và đảm bảo đối số e.Cancel không được đặt thành true bởi các sự kiện xác thực trên các điều khiển khác trên biểu mẫu. Tôi nghĩ rằng họ sẽ bị sa thải trước sự kiện FormClosing.

private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      if (e.CloseReason == CloseReason.UserClosing) 
      { 
       e.Cancel = false; 
       return; 
      } 
     } 
+0

Cách tiếp cận sạch sẽ, giống như nó^_ ^ – chad

0

Chỉ cần kiểm tra xem biểu mẫu sở hữu hộp văn bản có đang xử lý không? Nếu nó bị đóng, nó đang xử lý. Nếu nó xử lý bạn chỉ đơn giản là có thể kết thúc sự kiện 'rời' pesky mà không làm bất cứ điều gì. Tôi đã không kiểm tra nó và tha thứ cho tôi, tôi bị nghẹt thở trong một dự án của riêng tôi và tôi đang tìm kiếm bản thân mình, vì vậy tôi không nghĩ rằng tôi sẽ có thời gian cho điều đó.

private void GuiltyTextBox_Leave(object sender, EventArgs e) { 
    Form formOwningTheTextBox=(Form)((Control)sender).TopLevelControl; 
    if (formOwningTheTextBox.Disposing || formOwningTheTextBox.IsDisposed) return; 
    ....... 
} 

Tôi chỉ tin rằng điều này sẽ hoạt động với nỗ lực tối thiểu và muốn gửi câu trả lời nhanh trước khi tôi tiếp tục tìm kiếm câu trả lời của riêng mình.

0

Viết Sau dòng mã trong trường hợp văn bản hộp nghỉ trên đỉnh

if me.closing then 
return 
end if 
Các vấn đề liên quan