2008-10-02 12 views
10

Có cách nào để biểu mẫu chính có thể chặn các sự kiện kích hoạt trên một điều khiển con trên điều khiển người dùng không?Làm cách nào để lấy sự kiện từ các điều khiển phụ trên điều khiển người dùng trong ứng dụng WinForms?

Tôi có một điều khiển người dùng tùy chỉnh được nhúng trong Biểu mẫu chính của đơn đăng ký của tôi. Điều khiển chứa các phụ lục khác nhau điều khiển dữ liệu, bản thân nó được hiển thị bằng các điều khiển khác trên biểu mẫu chính. Điều tôi muốn là nếu biểu mẫu chính có thể được thông báo bằng cách nào đó khi người dùng thay đổi các liên kết phụ, vì vậy tôi có thể cập nhật dữ liệu và hiển thị tương ứng ở nơi khác.

Hiện tại, tôi đang lừa dối. Tôi có một đại biểu được nối với sự kiện tập trung rời khỏi các tiểu lục địa. Đại biểu này thay đổi thuộc tính của điều khiển người dùng mà tôi không sử dụng ở nơi khác (trong nguyên nhân này là CausesValidation). Sau đó tôi có một đại biểu được xác định trên biểu mẫu chính khi thuộc tính CausesValidation của người dùng kiểm soát thay đổi, sau đó hướng ứng dụng cập nhật dữ liệu và hiển thị. Một vấn đề phát sinh bởi vì tôi cũng có một đại biểu được thiết lập cho khi tập trung rời khỏi kiểm soát người dùng, bởi vì tôi cần phải xác nhận các trường trong điều khiển người dùng trước khi tôi có thể cho phép người dùng làm bất cứ điều gì khác. Tuy nhiên, nếu người dùng chỉ chuyển đổi giữa các liên kết phụ, tôi không muốn xác thực, bởi vì họ có thể không được chỉnh sửa xong.

Về cơ bản, tôi muốn dữ liệu cập nhật khi người dùng chuyển các liên kết phụ HOẶC rời khỏi điều khiển người dùng nhưng không xác thực. Khi người dùng rời khỏi điều khiển, tôi muốn cập nhật và xác thực. Ngay bây giờ, hãy để người dùng kiểm soát việc xác thực để kích hoạt hai lần.

+0

Điều gì sai khi buộc biểu mẫu chính đến các sự kiện khác nhau của các điều khiển? Có một tấn các sự kiện cháy cho hầu hết các điều khiển winform – Sekhat

+0

Tôi nghĩ rằng tôi chỉ không hiểu những gì bạn muốn đạt được: P – Sekhat

+0

Để trả lời câu hỏi đầu tiên, thông qua nhà thiết kế (đó là những gì tôi, tương đối mới với C#, đã được sử dụng để chỉnh sửa GUI của tôi), biểu mẫu của tôi chỉ có quyền truy cập vào các sự kiện được nâng lên bởi điều khiển người dùng chứ không phải các liên kết phụ của nó. Điều tôi không nhớ là tôi có thể tự mình tổ chức các sự kiện và xử lý các sự kiện đó. –

Trả lời

15

Cách tốt nhất là phơi bày các sự kiện trên UserControl làm bong bóng các sự kiện lên đến biểu mẫu gốc. Tôi đã đi trước và đưa ra một ví dụ cho bạn. Đây là một mô tả về những gì ví dụ này cung cấp.

  • UserControl1
    • Tạo một UserControl với TextBox1
    • đăng ký một sự kiện công cộng trên UserControl gọi ControlChanged
    • Trong UserControl đăng ký một xử lý sự kiện cho TextBox1 TextChangedEvent
    • Trong handler TextChangeEvent chức năng tôi gọi là.210 sự kiện vào bong bóng tới form cha
  • Form1
    • Thả một thể hiện của UserControl1 trên thiết kế
    • đăng ký một event handler trên UserControl1 cho MouseLeave và cho ControlChanged

Đây là ảnh chụp màn hình minh họa sự kiện ControlChanged mà tôi đã xác định trên UserControl có sẵn thông qua UX trong Visual Studio trên biểu mẫu Windows mẹ.

Event Handlers for User Control http://friendfeed.s3.amazonaws.com/0d5a3968cb785625c8afb3974a8d84894c476291

+0

Cảm ơn, đây là những gì tôi làm, ngoại trừ thay vì MouseLeave, tôi đã sử dụng FocusLeave, vì có khả năng gây lỗi mỗi lần người dùng di chuyển chuột của mình có thể bị kích thích. Ngoài ra, cảm ơn bạn đã trải qua tất cả công việc cho việc này! –

+0

vì vậy nếu bạn có nhiều điều khiển khác nhau (giả sử, hộp văn bản, nút, hộp kiểm và nhãn) và tất cả các sự kiện thích hợp/thực tế của kiểm soát được xử lý bên trong điều khiển người dùng (tự kiểm soát người dùng), và bạn muốn bong bóng lên một sự kiện (ví dụ MyControl.OnClick) tới biểu mẫu vùng chứa, bạn có thể "cướp" tất cả các sự kiện subcontrol thông qua một phương pháp/cơ chế để bong bóng sự kiện Click duy nhất, hoặc bạn vẫn phải bằng tay dây lên mỗi sự kiện subcontrol và xử lý bubbling mình cho mỗi một? – MaxOvrdrv

+1

Liên kết không hoạt động. Mã nên đi dưới dạng văn bản trong câu trả lời, không phải là liên kết để tải xuống tệp zip. – ardila

2

Mô hình tốt nhất cho loại điều này sẽ tạo các sự kiện tùy chỉnh trên điều khiển người dùng của bạn và tăng chúng vào thời điểm thích hợp.

Kịch bản của bạn khá phức tạp, nhưng không phải là chưa từng nghe thấy. (Tôi thực sự đang ở trong một chế độ rất giống với một trong những dự án hiện tại của mình.) Cách tôi tiếp cận nó là điều khiển người dùng chịu trách nhiệm về việc xác nhận riêng của nó. Tôi không sử dụng CausesValidation; thay vào đó, tại điểm kiểm soát người dùng thích hợp, tôi thực hiện xác thực thông qua một ghi đè của ValidateChildren(). (Điều này thường xảy ra khi người dùng nhấp vào "Lưu" hoặc "Tiếp theo" trên điều khiển người dùng, đối với tôi.)

Không quen với giao diện người dùng của bạn, điều đó có thể không đúng 100% cho bạn. Tuy nhiên, nếu bạn tăng các sự kiện tùy chỉnh (có thể với một EventArgs tùy chỉnh xác định có hay không để thực hiện xác nhận), bạn sẽ có thể nhận được nơi bạn muốn.

2

Bạn sẽ cần phải cấp điện cho các sự kiện mà bạn quan tâm chụp bên trong điều khiển người dùng của bạn, và xuất bản chúng thông qua một số tính chất sự kiện tùy chỉnh trên điều khiển người dùng riêng của mình. Một ví dụ đơn giản sẽ được gói một sự kiện nút bấm:

// CustomControl.cs 
// Assumes a Button 'myButton' has been added through the designer 

// we need a delegate definition to type our event 
public delegate void ButtonClickHandler(object sender, EventArgs e); 

// declare the public event that other classes can subscribe to 
public event ButtonClickHandler ButtonClickEvent; 

// wire up the internal button click event to trigger our custom event 
this.myButton.Click += new System.EventHandler(this.myButton_Click); 
public void myButton_Click(object sender, EventArgs e) 
{ 
    if (ButtonClickEvent != null) 
    { 
    ButtonClickEvent(sender, e); 
    } 
} 

Sau đó, trong Form sử dụng mà điều khiển, bạn dây lên sự kiện này như bạn sẽ bất kỳ khác:

// CustomForm.cs 
// Assumes a CustomControl 'myCustomControl' has been added through the desinger 
this.myCustomControl.ButtonClickEvent += new System.EventHandler(this.myCustomControl_ButtonClickEvent); 
myCustomControl_ButtonClickEvent(object sender, EventArgs e) 
{ 
    // do something with the newly bubbled event 
} 
+0

Có lẽ tôi sai hoặc tôi không thực sự hiểu ý tưởng, nhưng không nên có ' new MyProject.CustomControl.ButtonClickHandler() 'thay vì' new System.EventHandler() 'trong' CustomForm.cs'? – MRM

0

Tôi muốn kêu vang trong đó, như mô tả, nó thực sự âm thanh như bạn đang theo đuổi một cá trích đỏ. Trong khi nó có vẻ như bạn có một tình huống mà thiếu sự kiện bubbling trong WinForms gây ra rắc rối cho bạn, thực tế là một kiến ​​trúc nghèo là buộc bạn vào sự kiện cần bọt khi bạn không nên.

Nếu bạn có thể cấu trúc lại/thiết kế lại thiết kế của mình sao cho các điều khiển hoạt động với mô hình dữ liệu chung (MVC/MVP là lựa chọn hiển nhiên) thì bạn có thể áp dụng các mẫu WinForms phổ biến như các sự kiện PropertyChanged trên mô hình và bất kỳ điều khiển nào khác tiêu thụ dữ liệu đó để tự cập nhật.

Tóm lại, các câu trả lời khác là hợp lý để họ trả lời câu hỏi khi được hỏi. Nhưng từ quan điểm về chất lượng mã, tôi nghĩ câu trả lời tốt hơn là tách dữ liệu của bạn khỏi giao diện người dùng.

1

Trong trường hợp ai đó vẫn đang tự hỏi làm thế nào để mô phỏng sự kiện bubbling trong WinForm phương pháp Application.AddMessageFilter là một nơi tốt để xem xét.

Sử dụng phương pháp này, bạn có thể cài đặt bộ lọc của riêng bạn theo dõi tất cả các tin nhắn đang được đăng vào hàng đợi tin nhắn của chuỗi hiện tại.

Bạn nên lưu ý rằng các thư được gửi (không được đăng) không thể được xử lý bởi bộ lọc này.Các sự kiện thú vị nhất (như sự kiện nhấp chuột) được đăng và không được gửi và do đó có thể được theo dõi bởi bộ lọc này