Обработчики событий и делегаты (простой вопрос) - PullRequest
0 голосов
/ 10 июня 2011

У меня есть простое приложение.Вот как это работает.У меня есть класс (MyForm), который наследует от Windows.Forms.Он имеет кнопку, ярлык и текстовое поле.Это похоже на окно чата.Есть еще один класс (Cliente), который принимает массив строк и возвращает List с экземпляром MyForm для каждого элемента в массиве.

У меня есть третий класс (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();
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 10 июня 2011

Вот небольшой образец. Я использую интерфейс для удаления связи между 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 голосов
/ 10 июня 2011

Существует несколько способов сделать это.

  • Просто создайте метод на клиенте и вызывайте его из Prueba.Это простейшее и наиболее интуитивное решение.
  • Добавьте событие в Prueba, передайте экземпляр Prueba в Cliente и позвольте Cliente зарегистрироваться в этом событии.
  • Используйте некоторый тип глобального статического мессенджера.Использование событий или простая передача сообщений.
...