Có, điều này là có thể. Phương thức Application.Exit() lặp lại các biểu mẫu trong bộ sưu tập Application.OpenForms để gọi phương thức OnFormClosing() của chúng. Có một lỗi trong Winforms khiến cho bộ sưu tập đó mất dấu vết của các biểu mẫu mở. Mã này chứng minh điều đó:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnHandleCreated(EventArgs e) {
// Set breakpoint here:
base.OnHandleCreated(e);
}
protected override void OnMouseDown(MouseEventArgs e) {
this.ShowInTaskbar = !this.ShowInTaskbar;
MessageBox.Show(string.Format("There are {0} open forms", Application.OpenForms.Count));
Application.Exit();
}
protected override void OnFormClosing(FormClosingEventArgs e) {
MessageBox.Show("you won't see this");
base.OnFormClosing(e);
}
}
Nhấp vào biểu mẫu để kích hoạt lỗi. Lưu ý cách nó báo cáo 0 biểu mẫu mở và cách bạn chưa bao giờ thấy hộp thông báo được hiển thị trong OnFormClosing.
Đây là nhiệm vụ cho thuộc tính ShowInTaskbar gây ra nó. Có một số thuộc tính như vậy, tôi đã chọn ShowInTaskbar vì đó là một trong những bạn có khả năng sử dụng khi bạn có một NotifyIcon. RightToLeft là một số khác. Các thuộc tính này đặc biệt vì chúng chỉ có thể được chỉ định khi cửa sổ được tạo bằng hàm api CreateWindowEx() gốc. Thay đổi chúng đòi hỏi Winforms phải làm một cái gì đó khá anh hùng, nó phá hủy cửa sổ và tạo lại nó. Thật không may mà cũng gây ra lỗi, phá hủy cửa sổ cũng bị loại bỏ khỏi bộ sưu tập OpenForms và nó quên để thêm nó trở lại.
Sao chép/dán phương thức OnHandleCreated() từ đoạn mã này vào biểu mẫu của bạn và đặt điểm ngắt trên đó. Nó phải kích hoạt một lần, khi cửa sổ được tạo ra lần đầu tiên. Khi nó kích hoạt một lần nữa và do đó gọi kịch bản lỗi bạn có thể nhìn vào ngăn xếp cuộc gọi để xem mã nào trong lớp của bạn đã kích hoạt nó. Bạn sẽ phải tắt mã đó và tìm cách khác để thực hiện. Đặt thuộc tính ShowInTaskbar trong hàm tạo là tốt, nó chỉ xấu khi bạn gán nó sau khi cửa sổ được tạo, như trong trình xử lý sự kiện Load.
Nguồn
2012-11-23 10:35:10
Tôi tìm thấy khi 'ShowInTaskbar = false;' rằng 'Application.Exit()' không kích hoạt sự kiện 'FormClosing', khi nó thường xảy ra. –