E
E
Eugene2016-11-13 15:27:26
OOP
Eugene, 2016-11-13 15:27:26

How to change form textbox from another class?

Good day. I need to change the textbox value from another class, I was able to figure out how to do it with the help of this video . The only problem is that I was able to change the value of the textbox on button click. Here is a small example:

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;
    }
}

For my program, you need to make sure that the value of the box text changes without any button clicks. The bottom line is that as soon as the server receives a message from the user, it (the server) must not only send this message to all other connected users (the server.BroadcastMessage method is responsible for this), but also display it in the textbox of its form. Unfortunately, I can’t figure it out myself, I can’t display the text in the textbox in any way.
Here is the program code.
Server operation class:
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();
            }
        }
    }

Form class:
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));
        }
    }
}

I really hope that someone will help or tell you how to properly implement what I want.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Nemiro, 2016-11-13
@AlekseyNemiro

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;

   // }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question