5

Formデータを送信し、別のインスタンスからデータを受信できる Windows フォーム アプリケーションを作成する必要があります。つまり、Formはパブリッシャーとサブスクライバーの両方です。

残念ながら、その日は体調が悪く、その日は講義に出席できませんでした。

もう一度説明します:

Form新しいインスタンス ボタン、メッセージの受信、メッセージの送信を行う小さなチャットがあります。

すぐ下にあるように:

ここに画像の説明を入力

メッセージを送信すると、すべてのインスタンスの「受信済み」テキストボックスに表示されます。

デリゲートとイベントを使用する必要があると思います。

その方法は?ありがとう!!

4

1 に答える 1

9

簡単な解決策は次のとおりです。ご不明な点がある場合や、コメントがわかりにくい場合はお知らせください。

これが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クラスです。メッセージクラスはシングルトン(つまり、1回だけインスタンス化できます)であり、フォームのすべてのインスタンスで1つのリストを永続化できます。すべてのフォームは同じリストを共有し、リストが更新されるたびに通知を受け取ります。ご覧のとおり、「HandleMessage」イベントは、各フォームが作成/表示されるたびにサブスクライブするイベントです。

NotifyNewMessage関数を見ると、これは、変更があったことをサブスクライブに通知するために、Messagesクラスによって呼び出されます。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コントロールの「View」プロパティを「List」に設定することを忘れないでください。より簡単な(そして好ましい方法)のは、単にObservableCollectionリストタイプを使用することです。これは、サブスクライブできるイベントをすでに提供しています。

お役に立てれば。

于 2012-12-05T10:09:19.747 に答える