@haintass
IT-падаван

Как изменить textbox формы из другого класса?

Доброго времени суток. Мне необходимо изменять значение textbox из другого класса, смог разобраться как это делать с помощью данного видео. Единственная проблема в том, что я смог изменять значение textbox при нажатии кнопки. Вот небольшой пример:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Worker _worker;
 
        public Form1()
        {
            InitializeComponent();
 
            sendMessageButton.Click += Button1_Click;
        }
 
        private void Button1_Click(object sender, EventArgs e)
        {
            _worker = new Worker();
 
            _worker.SendMessage += _worker_SendMessage1;
 
            Thread thread = new Thread(_worker.Work);
            thread.Start();
 
            if (_worker != null)
                _worker.SendMessageToTB();
        }
 
        private void _worker_SendMessage1(string mess)
        {
            ChatTextBox.Invoke((MethodInvoker)(() => ChatTextBox.Text += mess));
        }
    }
 
    public class Worker
    {
        private string mess = "Кажется, ты что-то нажал...\r\n";
        private bool _sendMessage = false;
 
        public void SendMessageToTB()
        {
            _sendMessage = true;
        }
 
        public void Work()
        {
            if (_sendMessage)
            {
                SendMessage(mess);
                _sendMessage = false;
            }
        }
 
        public event Action<string> SendMessage;
    }
}

Для моей же программы нужно сделать так, чтобы значение текст бокса изменялось без всяких нажатий на кнопку. Суть в том, что как только серверу от пользователя приходит сообщение, он (сервер) должен это сообщение не только отправить всем остальным подключенным пользователям (за это отвечает метод server.BroadcastMessage), но и вывести в textbox своей формы. К сожалению сам так и не могу с этим разобраться, никак не выводится у меня текст в textbox.
Вот код программы.
Класс работы сервера:
public class ClientObject
    {
        public event Action<string> SendMessage;
 
        internal string Id { get; private set; }
        internal NetworkStream Stream { get; set; }
        string userName;
        TcpClient client;
        ServerObject server;
 
        public ClientObject() { }
        public ClientObject(TcpClient tcpClient, ServerObject serverObject)
        {
            Id = Guid.NewGuid().ToString();
            client = tcpClient;
            server = serverObject;
            server.AddConnection(this);
        }
 
        public void Process()
        {
            try
            {
                // Возвращаем объект NetWorkStream, используемый для отправки и получения данных
                Stream = client.GetStream();
 
                // Получаем имя пользователя
                userName = GetMessage();
                string message = userName + " вошел в чат.";
                // Рассылаем сообщение о входе в чат всем подключенным пользователям
                server.BroadcastMessage(message, Id); // отправляем сообщение всем подключенным пользователям
                SendMessage(message); // Данный текст должен быть записан в textbox формы
 
                // Получаем данные от пользователя
                while (true)
                {
                    try
                    {
                        message = GetMessage();
                        message = string.Format($"{userName}: {message}");
                        server.BroadcastMessage(message, Id);
                        SendMessage(message); // Данный текст должен быть записан в textbox формы
                    }
                    catch
                    {
                        message = userName + " покинул чат.";
                        server.BroadcastMessage(message, Id);
                        SendMessage(message); // Данный текст должен быть записан в textbox формы
                        break;
                    }
                }
            }
            catch
            {
                //Когда-нибудь здесь что-то будет...
            }
            finally
            {
                // Удаляем пользователя из списка подключенных пользователей и закрываем поток с соединением
                server.RemoveConnection(Id);
                Close();
            }
        }
    }

Класс формы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
 
namespace Server
{
    public partial class Form1 : Form
    {
        static ServerObject server;
        static Thread listenerThread;
 
        private ClientObject cl = new ClientObject();
 
        public Form1()
        {
            InitializeComponent();
 
            cl.SendMessage += Cl_SendMessage; // Подписываемся на событие
 
            try
            {
                server = new ServerObject();
                listenerThread = new Thread(new ThreadStart(server.Listen));
                listenerThread.Start(); // старт потока
            }
            catch (Exception exc)
            {
                server.Disconnect();
            }
        }
 
        private void Cl_SendMessage(string mess)
        {
            chatLogTB.Invoke((MethodInvoker)(() => chatLogTB.Text += mess));
        }
    }
}

Очень надеюсь, что кто-нибудь поможет или подскажет как правильно реализовать то, что я хочу.
  • Вопрос задан
  • 1236 просмотров
Пригласить эксперта
Ответы на вопрос 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
private void Cl_SendMessage(string mess)
{
    // если метод вызывается не из потока, к которому привязана форма
    // https://msdn.microsoft.com/ru-ru/library/system.windows.forms.control.invokerequired.aspx
    if (this.InvokeRequired)
    {
      // делаем вызов из потока формы
      // https://msdn.microsoft.com/ru-ru/library/zyzhdc6b.aspx
      this.Invoke(new Action<string>(this.Cl_SendMessage), mess);
      // уходим из этого метода
      return;
      // или можно в условии сделать else
      // кому как больше нравится
    }
    // else {

    // код находящийся здесь будет выполняться только если 
    // текущий поток - это поток в котором находится форма
    chatLogTB.Text += mess;

   // }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы