2012-12-05 1 views
5

Ich muss eine Windows Form-Anwendung erstellen, die in der Lage ist, Daten zu senden und Daten von einer anderen Form Instanz zu empfangen. Was bedeutet, die Form ist ein Herausgeber und ein Abonnent, beide von ihnen.Wie verwenden Sie Ereignisse und delegieren Sie, um Daten zwischen Formularen zu senden?

Leider war ich an diesem Tag krank, und ich konnte an diesem Tag nicht in der Vorlesung sein.

Ich werde wieder erklären:

Ich habe einen kleinen Plausch Form, , die haben: neue Instanz Taste, empfangene Nachrichten und senden Mitteilung.

wie Sie rechts unten sehen können:

enter image description here

Wenn ich eine Nachricht zu senden, wird es in der „Recieved“ Textbox aller Instanzen angezeigt.

Ich denke, dass ich Delegaten und Ereignisse verwenden muss.

Wie geht das? Vielen Dank!!

+0

Werfen Sie einen Blick auf das "Beobachter" -Muster. http://msdn.microsoft.com/en-us/library/ee817669.aspx –

Antwort

7

Hier ist eine schnelle Lösung .. Lassen Sie mich wissen, wenn Sie Fragen haben oder wenn Sie die Kommentare verwirrend finden ..

Hier ist die Form-Klasse (Code-behind). Beachten Sie, dass nach der Instanziierung des Formulars ein Ereignis "abonniert" wird, indem ein Ereignishandler mit dem HandleMessage-Ereignis in der Message-Klasse verknüpft wird. Innerhalb der Form-Klasse wird die Elementauflistung der ListView aufgefüllt.

Jedes Mal, wenn die Schaltfläche Neue Formulars geklickt wird, das gleiche Formular gets erstellt und angezeigt (dies erlaubt Wiederverwendung von Code, da die gleiche Logik genau für alle Instanzen des Formulars wird die gleiche sein)

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); 
    } 
} 

}

Hier ist eine Nachrichtenklasse, die ich erstellt habe, um eine "zentrale" Liste von Nachrichten zu verarbeiten, die zwischen Forms gesendet werden. Die Nachrichtenklasse ist ein Singleton (dh sie kann nur einmal instanziiert werden), wodurch eine Liste in allen Instanzen eines Formulars beibehalten werden kann. Alle Formulare teilen dieselbe Liste und werden benachrichtigt, sobald eine Liste aktualisiert wurde. Wie Sie sehen können, ist das "HandleMessage" -Ereignis das Ereignis, das jedes Formular abonnieren wird, wenn es erstellt/angezeigt wird.

Wenn Sie sich die NotifyNewMessage-Funktion ansehen, wird diese von der Messages-Klasse aufgerufen, um die Abonnenten zu benachrichtigen, dass eine Änderung stattgefunden hat. Da EventArgs verwendet wird, um Daten an die Abonnenten weiterzugeben, habe ich spezielle EventArgs erstellt, um die neu hinzugefügten Nachrichten an alle Abonnenten weiterzuleiten.

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; 
     } 
    } 
} 

Auch .., um für die Meldungen „angezeigt“ korrekt sein, nicht zu vergessen die legen Sie die „Ansicht“ Eigenschaft des Listview-Steuerelement „List“. Ein einfacherer (und bevorzugterer) Weg wäre die Verwendung des Listentyps ObservableCollection, der bereits ein Ereignis bietet, das Sie abonnieren können.

Hoffe, das hilft.

+0

Ok, danke, ich werde es versuchen, wenn ich zuhause bin (weil ich ubuntu auf meinem Laptop benutze). Könntest du mir bitte kurz beschreiben, was hast du da geschrieben? – Billie

+0

@ user1798362 aktualisiert, um weitere Informationen zur Verfügung zu stellen. Lassen Sie mich wissen, wenn Sie weitere Fragen haben. –

+0

Es verwendet keine Delegierten und Ereignisse, aber die Idee ist klar. Vielen Dank. – Billie