#c# #.net #c#-4.0
#c# #.net #c #-4.0
Вопрос:
У меня есть простое приложение. Вот как это работает. У меня есть класс (MyForm), который наследуется от Windows.Формы. В нем есть кнопка, метка и текстовое поле. Это похоже на окно чата. Существует другой класс (Cliente), который принимает массив строк и возвращает список с экземпляром 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();
}
}
}
Ответ №1:
Вот небольшой пример. Я использую интерфейс, чтобы удалить связь между MainWindow и окнами чата.
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));
}
}
Ответ №2:
На самом деле существует несколько способов сделать это.
- Просто создайте метод в Cliente и вызовите его из Prueba. Это самое простое и интуитивно понятное решение.
- Добавьте событие в Prueba, передайте экземпляр Prueba Cliente и позвольте Cliente зарегистрироваться для этого события.
- Используйте какой-нибудь глобальный статический класс messenger. Либо с использованием событий, либо простой передачей сообщений.