2012-08-29 42 views
1

有人能告訴我如何在我的UserControl中擁有一項功能,這可以讓主窗口窗體知道控件在做什麼?從UserControl獲取更新

例如我的用戶控件有一個文件瀏覽器,如果用戶使用這個文件瀏覽器打開一個文件,我想在我的表單的statusstrip欄中寫入「加載文件」。

這是否需要使用事件?如果是這樣,我怎麼能在usercontrol裏面有一個事件來報告它所做的事情(然後我想我必須在usercontrol的所有方法中調用這個事件)。

回答

1

是的,您需要創建一個事件並訂閱它。遵循事件的標準模式的一個建議:

enum ControlStatus {Idle, LoadingFile, ...} 

class StatusChangedEventArgs : EventArgs 
{ 
    public ControlStatus Status {get; private set;} 

    public StatusChangedEventArgs(ControlStatus status) 
     : base() 
    { 
     this.Status = status; 
    } 
} 

partial class MyControl : UserControl 
{ 
    public ControlStatus Status {get; private set;} 

    public event EventHandler<StatusChangedEventArgs> StatusChanged; 

    protected virtual void OnStatusChanged(StatusChangedEventArgs e) 
    { 
     var hand = StatusChanged; 
     if(hand != null) hand(this, e); 
    } 

    void LoadFiles() 
    { 
     ... 

     Status = ControlStatus.LoadingFiles; 
     OnStatusChanged(new StatusChangedEventArgs(this.Status)); 

     ... 

     Status = ControlStatus.Idle; 
     OnStatusChanged(new StatusChangedEventArgs(this.Status)); 
    } 
} 

partial class MyHostWindowsForm : Form 
{ 
    public MyHostWindowsForm() 
    { 
     var ctl = new MyControl(); 
     ... 
     ctl.StatusChanged += ctl_StatusChanged; 
    } 

    void ctl_StatusChanged(object sender, StatusChangedEventArgs e) 
    { 
     switch(e.Status) 
     { 
      case ControlStatus.Idle: 
       statusStripBar.Text = null; 
       break; 
      case ControlStatus.LoadingFiles: 
       statusStripBar.Text = "Loading file(s)"; 
       break; 
      ... 
     } 
    } 
} 
2

簡單

是,暴露用戶控件的形式可以訂閱的事件。你應該使用標準的事件模式:當文件被打開

class MyUserControl : UserControl 
{ 
    public event EventHandler<EventArgs> FileOpened; 

    protected virtual void OnFileOpened(EventArgs e) 
    { 
     EventHandler<EventArgs> handler = FileOpened; 
     if (handler != null) 
      handler(this, e); 
    } 
} 

然後調用OnFileOpened(EventArgs.Empty)其觸發事件。

使用自定義的EventArgs

現在的形式很可能需要知道被打開了哪些文件。你可以在公開的表格可以用來找出用戶控件的屬性,也可以提供這些信息在你的事件,像這樣:

public class FileOpenedEventArgs : EventArgs 
{ 
    private string filename; 
    public FileOpenedEventArgs(string filename) 
    { 
     this.filename = filename; 
    } 
    public string Filename { get { return filename; } } 
} 

class MyUserControl : UserControl 
{ 
    public event EventHandler<FileOpenedEventArgs> FileOpened; 

    protected virtual void OnFileOpened(FileOpenedEventArgs e) 
    { 
     EventHandler<FileOpenedEventArgs> handler = FileOpened; 
     if (handler != null) 
      handler(this, e); 
    } 
} 

然後你OnFileOpened(new FileOpenedEventArgs(filename))觸發事件。

最優

當你創建一個事件處理程序public event delegate Name;,你分配你的對象的委託保管。對象(尤其是控件)通常具有大量從不訂閱的事件。這是一大堆沒有被使用的分配存儲。在框架中有一個以EventHandlerList爲形式的優化。這個方便的對象只有在實際使用時才存儲事件處理程序。所有System.Windows.Forms.Control對象都來自System.ComponentModel.Component,它已經提供了一個(受保護的)EventHandlerList,您可以在派生控件中訪問該對象。

要使用它,首先要創建一個可以唯一標識事件的靜態對象,然後手動提供add {}remove {}方法。像這樣:

class MyUserControl : UserControl 
{ 
    private static readonly object FileOpenedKey = new Object(); 
    public event EventHandler<FileOpenedEventArgs> FileOpened 
    { 
     add { Events.AddHandler(FileOpenedKey, value); } 
     remove { Events.RemoveHandler(FileOpenedKey, value); } 
    } 

    protected virtual void OnFileOpened(FileOpenedEventArgs e) 
    { 
     var handler = (EventHandler<FileOpenedEventArgs>)Events[FileOpenedKey]; 
     if (handler != null) 
      handler(this, e); 
    } 
}