2011-06-10 62 views
0

我有一個簡單的應用程序。這是它的工作原理。我有一個繼承自Windows.Forms的類(MyForm)。它有一個按鈕,一個標籤和一個文本框。它看起來像一個聊天窗口。 還有另一個類(Cliente)需要一個字符串數組,它會爲數組中的每個元素返回一個帶有MyForm實例的List。事件處理程序和代表(簡單問題)

我有第三類(Prueba),利用前兩個類來測試它們。這個類創建MyForm的四個實例,並顯示它們。 (我會省略一些代碼和功能,因爲我知道它工作正常。)

我需要能夠在一個窗口中鍵入內容,並且當點擊按鈕時,它應該廣播此消息並將其顯示在所有其他視窗。 我知道我必須使用事件處理程序和代表,但經過幾個小時的教程,我無法弄清楚要放哪裏。

你能幫我嗎?如果你能指點我一個很好的教程或例子就足夠了,但如果你可以對我的代碼更具體,它會很棒。 (我不知道如何讓MyForm的一個實例知道其他實例,誰應該是這裏的監聽者?我在想客戶端,但我不知道該怎麼做)。 任何幫助將不勝感激!

//MyForm 
    namespace Dia26 { 

     //public delegate void ChangedEventHandler(object sender, EventArgs e); 

     public class MyForm : System.Windows.Forms.Form { 
      public Button btn = new Button(); 
      public TextBox textbox = new TextBox(); 
      public Label label = new Label(); 
      public Button btnEnviar = new Button(); 

      public delegate void OwnerChangedEventHandler(string newOwner); //~ 
      public event OwnerChangedEventHandler OwnerChanged; 

      protected void btn_Click(object sender, System.EventArgs e) { 
       this.Close(); 
      } 

      protected void btnEnviar_Click(object sender, System.EventArgs e) { 
       label.Text += textbox.Text + "\n"; 
       textbox.Text = ""; 
       if (this.OwnerChanged != null) { 
        this.OwnerChanged("something?"); 
       } 
      } 

      public MyForm() { 
       btn.Text = "cerrar"; 
       btn.Left = 400; 
       btn.Top = 280; 
       btn.Click += new EventHandler(this.btn_Click); 
       btnEnviar.Click += new EventHandler(this.btnEnviar_Click); 

       textbox.Left = 15; 
       textbox.Top = 20; 
       textbox.Width = 330; 

       label.Left = 15; 
       label.Top = 50; 
       label.AutoSize = false; 
       label.Height = 210; 
       label.Width = 450; 
       label.BackColor = Color.White; 

       btnEnviar.Left = 350; 
       btnEnviar.Top = 17; 
       btnEnviar.Text = "Enviar"; 

       this.Controls.Add(textbox); 
       this.Controls.Add(label); 
       this.Controls.Add(btn); 
       this.Controls.Add(btnEnviar); 

       this.SuspendLayout(); 
       this.Name = "MyForm"; 
       this.ResumeLayout(false); 

       return; 
      } 
     } 
    } 


    //Cliente.cs 
namespace Dia26Prueba { 
    public class Cliente { 
     public int creadas; 
     public int nocreadas; 

     public List<MyForm> MostrarVentanas(out bool error, ref int creadas, params string[] nombres) { 
      List<MyForm> list = new List<MyForm>(); 

      int bienCreadas = 0; 
      foreach (string str in nombres) { 
       if (str.Length >= 1) { 
        MyForm mf = new MyForm(); 
        mf.Text = str; 
        //mf.OwnerChanged += new OwnerChangedEventHandler(mf_OwnerChanged); 
        list.Add(mf); 
        mf.Show(); 
        bienCreadas++; 
       } 
      } 

      error = (bienCreadas == creadas); 
      nocreadas = bienCreadas - creadas; 
      creadas = bienCreadas; 

      return list; 
     } 

     public void ModificarPosicionYMedidas(MyForm mf, int x = 262, int y = 209, int width = 500, int height = 350) { 
      mf.Left = x; 
      mf.Top = y; 
      mf.Width = width; 
      mf.Height = height; 
     } 
    } 
} 

// Prueba 
namespace Dia29 { 
    class Prueba { 
     static void Main(string[] args) { 
      Cliente cliente = new Cliente(); 
      int n = 4; 

      Console.WriteLine(cliente.Autor); 

      if (args.Length != n) { 
       return; 
      } 

      int InstanciasCreadas = n; 
      bool HayErrores; 
      List<Dia26.MyForm> list; 

      list = cliente.MostrarVentanas(
       creadas: ref InstanciasCreadas, 
       error: out HayErrores, 
       nombres: new string[] { "FirstWindow", "2nd", "3rd", "4th" }); 

      cliente.ModificarPosicionYMedidas(list.ElementAt<MyForm>(0), 0, 0, 512, 384); 
      cliente.ModificarPosicionYMedidas(list.ElementAt<MyForm>(1), 512, 0, 512, 384); 
      cliente.ModificarPosicionYMedidas(list.ElementAt<MyForm>(2), 0, 384, 512, 384); 
      cliente.ModificarPosicionYMedidas(list.ElementAt<MyForm>(3), 512, 384, 512, 384); 

      for (int i = 0; i < n; i++) { 
       // ..... 
       Application.Run(list.ElementAt<MyForm>(i)); 
      }   


      Console.ReadLine(); 
     } 
    } 
} 

回答

0

這是一個小樣本。我正在使用一個接口去除MainWindow和ChatWindows之間的耦合。

public class ChatEventArgs : EventArgs 
{ 
    public string ChatEventArgs(string message) 
    { 
     Message = message; 
    } 

    public string Message { get; private set; } 
} 


public interface IChatMessageProvider 
{ 
    event EventHandler<ChatEventArgs> MessageArrived; 
    void TriggerEvent(object source, ChatEventArgs args); 
} 

public class MainWindow : IChatMessageProvider 
{ 
    public event EventHandler<ChatEventArgs> MessageArrived = delegate{}; 

    public void AddChatWindow() 
    { 
     ChatWindow window = new ChatWindow(this); 
     window.Show(); 
    } 

    public void TriggerEvent(object source, ChatEventArgs args) 
    { 
     MessageArrived(source, args); 
    } 
} 

public class ChatWindow : 
{ 
    IChatMessageProvider _provider; 

    public ChatWindow(IChatMessageProvider provider) 
    { 
     _provider = provider; 
     provider.MessageArrived += OnMessage; 
    } 


    public void OnMesage(object source, ChatEventArgs args) 
    { 
     // since we could have sent the message 
     if (source == this) 
      return; 

     myListBox.Items.Add(args.Message); 
    } 

    public void SendButton_Click(object source, EventArgs e) 
    { 
     _provider.TriggerEvent(this, new ChatEventArgs(Textbox1.Text)); 
    } 
} 
+0

謝謝!我很感激! – Eric 2011-06-12 04:03:03

0
+0

我會,我已經在Java中使用它作爲一個事實,唯一的問題是,我應該只使用原始事件處理程序和委託...任何其他想法? :) – Eric 2011-06-10 05:02:51

+0

鏈接中的示例確實使用事件處理程序和代理。你確定這不適合你? – alexD 2011-06-10 05:31:48

+0

事件本身就是觀察者模式的實現。因此告訴使用Observer模式與告訴使用事件相同。 – Euphoric 2011-06-10 05:48:55

0

有actualy多種方式來做到這一點。

  • 只需在Cliente上製作方法,然後從Prueba中調用它。這是最簡單和最直觀的解決方案。
  • 將活動添加到Prueba,將Prueba的實例傳遞給Cliente,讓Cliente註冊參加此活動。
  • 使用某種全局靜態消息類。無論是使用事件,還是簡單的消息傳遞。