开发者

Event Handlers & delegates (Simple Question)

开发者 https://www.devze.com 2023-03-12 01:51 出处:网络
I have a simple application. Here\'s how it works. I have a class (MyForm) that inherits from Windows.Forms. It has a button, a label and a textbox. It looks like a chat window.

I have a simple application. Here's how it works. I have a class (MyForm) that inherits from Windows.Forms. It has a button, a label and a textbox. It looks like a chat window. There's another class (Cliente) that takes an array of strings and it returns a List with a MyForm instance for each element in the array.

I have a third class (Prueba) that makes use of the previous two classes to test them. This class creates four instances of MyForm, and displays them. (I will omit some code and functionality because I know it works correctly.)

I need to be able to type something in one window and when click on the button, it should broadcast this message and display it in all the other windows. I know I have to use event handlers and delegates, but after hours of looking at tutorials everywhere I can't figure out what to put where.

Would you please help me? If you can point me to a good tutorial or example it'd be enough, but if you can be more specific on my code, it'd be great.

(I can't figure out how to make one instance of MyForm be aware of the other instances, who should be t开发者_C百科he listener here? I was thinking that Client, but I can't see how to do it.) Any help will be appreciated!

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


Here is a small sample. I'm using a interface to remove the coupling between the MainWindow and the 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));
    }
}


There are actualy multiple ways to do it.

  • Simply make method on Cliente and call it from Prueba. This is simplest and most intuitive solutoin.
  • Add event to Prueba, pass instance of Prueba to Cliente and let Cliente register to this event.
  • Use some kind of global static messenger class. Either using events, or simple message passing.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号