2012-12-05 18 views
5

我需要創建一個Windows窗體應用程序,它能夠發送數據並從另一個Form實例接收數據。什麼意思,Form是一個發佈者和訂閱者,他們都是。如何使用事件和委託在表單之間發送數據?

不幸的是,那天我病了,那天我不能參加演講。

我再解釋一下:

我有一個小小的聊天Form, 誰擁有新的Instance按鈕,接收到的消息,併發送消息。

,你可以看到下方:

enter image description here

當我發送郵件,它會在所有情況下的「收到」文本框中顯示。

我想我需要使用委託和事件。

如何做?謝謝!!

+0

看看「觀察者」模式。 http://msdn.microsoft.com/en-us/library/ee817669.aspx –

回答

7

這裏有一個快速的解決方案。讓我知道如果您有任何疑問,或者如果您發現該評論混亂..

這裏的Form類(代碼後面)。注意,一旦表單被實例化,它通過將事件處理程序「連線」到Message類中的HandleMessage事件來「訂閱」事件。在Form類中,這是ListView的項目集合被填充的位置。

每當新表單按鈕後,相同的形式獲取的創建和顯示(這允許代碼複用,因爲同樣的邏輯將是表格的所有實例完全一樣)

public partial class Form1 : Form 
{ 
    Messages _messages = Messages.Instance; // Singleton reference to the Messages class. This contains the shared event 
              // and messages list. 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Form1"/> class. 
    /// </summary> 
public Form1() 
{ 
    InitializeComponent(); 

    // Subscribe to the message event. This will allow the form to be notified whenever there's a new message. 
    // 
    _messages.HandleMessage += new EventHandler(OnHandleMessage); 

    // If there any existing messages that other forms have sent, populate list with them. 
    // 
    foreach (var messages in _messages.CurrentMessages) 
    { 
     listView1.Items.Add(messages); 
    } 
} 

/// <summary> 
/// Handles the Click event of the buttonNewForm control. 
/// </summary> 
/// <param name="sender">The source of the event.</param> 
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
private void buttonNewForm_Click(object sender, EventArgs e) 
{ 
    // Create a new form to display.. 
    // 
    var newForm = new Form1(); 
    newForm.Show(); 
} 

/// <summary> 
/// Handles the Click event of the buttonSend control. Adds a new message to the "central" message list. 
/// </summary> 
/// <param name="sender">The source of the event.</param> 
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
private void buttonSend_Click(object sender, EventArgs e) 
{ 
    string message = String.Format("{0} -- {1}", DateTime.UtcNow.ToLongTimeString(), textBox1.Text); 
    textBox1.Clear(); 
    _messages.AddMessage(message); 
} 

/// <summary> 
/// Called when [handle message]. 
/// This is called whenever a new message has been added to the "central" list. 
/// </summary> 
/// <param name="sender">The sender.</param> 
/// <param name="args">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
public void OnHandleMessage(object sender, EventArgs args) 
{ 
    var messageEvent = args as MessageEventArgs; 
    if (messageEvent != null) 
    { 
     string message = messageEvent.Message; 
     listView1.Items.Add(message); 
    } 
} 

}

下面是我創建的一個Messages類,用於處理在Forms之間發送的消息的「中央」列表。 Messages類是一個單例(也就是說,它只能被實例化一次),它允許一個列表在一個Form的所有實例中被保存。所有表單將共享相同的列表,並在列表更新時得到通知。正如您所看到的,「HandleMessage」事件是每個表單在創建/顯示時都會訂閱的事件。

如果查看NotifyNewMessage函數,Message類會調用此函數來通知訂閱者存在更改。由於使用EventArgs將數據傳遞給訂閱者,因此我創建了一個特殊的EventArgs將新添加的消息傳遞給所有訂閱者。

class Messages 
{ 
    private List<string> _messages = new List<string>(); 
    private static readonly Messages _instance = new Messages(); 
    public event EventHandler HandleMessage; 

    /// <summary> 
    /// Prevents a default instance of the <see cref="Messages"/> class from being created. 
    /// </summary> 
    private Messages() 
    { 
    } 

    /// <summary> 
    /// Gets the instance of the class. 
    /// </summary> 
    public static Messages Instance 
    { 
     get 
     { 
      return _instance; 
     } 
    } 

    /// <summary> 
    /// Gets the current messages list. 
    /// </summary> 
    public List<string> CurrentMessages 
    { 
     get 
     { 
      return _messages; 
     } 
    } 

    /// <summary> 
    /// Notifies any of the subscribers that a new message has been received. 
    /// </summary> 
    /// <param name="message">The message.</param> 
    public void NotifyNewMessage(string message) 
    { 
     EventHandler handler = HandleMessage; 
     if (handler != null) 
     { 
      // This will call the any form that is currently "wired" to the event, notifying them 
      // of the new message. 
      handler(this, new MessageEventArgs(message)); 
     } 
    } 

    /// <summary> 
    /// Adds a new messages to the "central" list 
    /// </summary> 
    /// <param name="message">The message.</param> 
    public void AddMessage(string message) 
    { 
     _messages.Add(message); 
     NotifyNewMessage(message); 
    } 
} 

/// <summary> 
/// Special Event Args used to pass the message data to the subscribers. 
/// </summary> 
class MessageEventArgs : EventArgs 
{ 
    private string _message = string.Empty; 
    public MessageEventArgs(string message) 
    { 
     _message = message; 
    } 

    public String Message 
    { 
     get 
     { 
      return _message; 
     } 
    } 
} 

還..爲了使信息是「顯示」正確,不設定「查看」 ListView控件的屬性忘記「列表」。一個更簡單(和首選的方法)只是使用ObservableCollection列表類型,它已經提供了一個您可以訂閱的事件。

希望這會有所幫助。

+0

好的,謝謝,我會在家時嘗試它(因爲我在我的筆記本電腦上使用Ubuntu)。你能否簡要介紹一下你在那裏寫了些什麼? – Billie

+0

@ user1798362已更新,以提供更多信息。如果您有任何疑問,請告知我們。 –

+0

它不使用委託和事件,但想法很明確。謝謝。 – Billie