Accessing GUI from another class

I am trying to make a client server program. The server code is as pas

Page 1 of 1

8 Replies - 1994 Views - Last Post: 18 August 2009 - 11:20 PM Rate Topic: -----

#1 khedarnath  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-January 09

Accessing GUI from another class

Posted 16 August 2009 - 07:03 AM

I am trying to make a client server program. The server code is as pasted below. When the server get a response from the client, say a string it needs
to update the form showing the string in a textbox. I have tried a method here but it doesn't work. I am happy if someone could help me solving this problem.

The client server communication is working properly.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace serv
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}
		public void updateText(string text)
		{
			textBox1.Text = text;
		}
		private void button1_Click(object sender, EventArgs e)
		{
			Thread server = new Thread(new ThreadStart(runserv));
			server.Start();
		}
		void runserv()
		{
			
			TcpListener sev = new TcpListener(IPAddress.Any, 5555);
			sev.Start();
			Console.WriteLine("Waiting for connection");
			while (true)
			{
				while (!sev.Pending())
				{
					Thread.Sleep(1000);
				}
				ConnectionThread newconn = new ConnectionThread(sev);
			}
		}

		private void button2_Click(object sender, EventArgs e)
		{
			
		}

		private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
		{
			TcpClient cl = shared.onLineusers[listBox1.SelectedIndex].myTcp;
			NetworkStream ns = cl.GetStream();
			//send getclipboard message
			ns.Write(ASCIIEncoding.ASCII.GetBytes("2getCB"),0,"2getCB".Length);
		}
	}
	class ConnectionThread
	{
		TcpListener threadListener;
		Form1 f = new Form1();
		delegate void setTextCallback(TextBox tbox, string text);
		string makeSysMsg(int msgType, string msg)
		{
			return Convert.ToString(msgType) + msg;
		}

		public ConnectionThread(TcpListener lis)
		{
			threadListener = lis;
			Thread newthread = new Thread(new ThreadStart(HandleConnection));
			newthread.Start();
		}
		void setText(TextBox tbox,string text)
		{
			tbox.Text = text;
		}
		public void HandleConnection()
		{
			byte[] data = new byte[1024];
			if (f.textBox1.InvokeRequired)
			{
				setTextCallback fun = new setTextCallback(setText);
				this.f.Invoke(fun, new object[] { f.textBox1, "khedar" });
			}
			int myId = 0;
			int UPDATE_LIST = 2;

			//accept client
			TcpClient client = threadListener.AcceptTcpClient();
			NetworkStream ns = client.GetStream();
			NetworkStream pairns = null;

			//send welcome message
			string mesg ="1Welcome";
			data = Encoding.ASCII.GetBytes(mesg);
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			//recieve machineName
			data = new byte[1024];
			int recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineName =  ASCIIEncoding.ASCII.GetString(data).Trim('\0');

			//recieve machineIP
			/*data = new byte[1024];
			recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineIP = ASCIIEncoding.ASCII.GetString(data);*/
			
			//add to list and refresh listbox
			user curuser=new user(client,machineName,shared.onLineusers.Count+1);
			shared.onLineusers.Add(curuser);
			refreshList();

			//send getCB msg
			 mesg= "2getCB";
			 data = Encoding.ASCII.GetBytes(mesg); ns.Flush();
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			while (true)
			{
				data = new byte[1024];
				recv = 0;
				try
				{
					recv = ns.Read(data, 0, data.Length);
					int a = 19;
				}
				catch (System.IO.IOException r) {MessageBox.Show(r.ToString()); }
				//Console.WriteLine(Encoding.ASCII.GetString(data));
				
				if (recv == 0)
					break;
				string msg = ASCIIEncoding.ASCII.GetString(data);
				int msgType = Convert.ToInt32(msg[0]) - 48;
				if ((msgType == 1) | (msgType == 2) | (msgType == 3) | (msgType == 4) | (msgType == 5))
				{

					msg = msg.Substring(1);
				}
				switch (msgType)
				{
					case 2://recieve the clipboard text
						 //HERE IS THE PROBLEM
						f.updateText(msg);
						//f.textBox1.Text = msg;
						break;
					case 4://its a login request
						break;
					case 5://its an ordinary message
						msg = makeSysMsg(5, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
					case 6://its a chat message
						msg = makeSysMsg(6, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
				}
			}
			ns.Close();
			client.Close();
		}
		void refreshList()
		{
			f.listBox1.Items.Clear();
			for (int i = 0; i < shared.onLineusers.Count; i++)
			{
				f.listBox1.Items.Add(shared.onLineusers[i].name);
			}
		}
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Accessing GUI from another class

#2 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 942
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Accessing GUI from another class

Posted 17 August 2009 - 12:01 PM

I have seen this before. Telling the textbox to redraw itself after setting the text should solve your problem. I know it solved a similar problem when a class outside of the form was updating a textbox.

		public void updateText(string text)
		{
			textBox1.Text = text;
			textBox1.Invalidate();
		}


Was This Post Helpful? 0
  • +
  • -

#3 khedarnath  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-January 09

Re: Accessing GUI from another class

Posted 17 August 2009 - 01:17 PM

View PostSixOfEleven, on 17 Aug, 2009 - 11:01 AM, said:

I have seen this before. Telling the textbox to redraw itself after setting the text should solve your problem. I know it solved a similar problem when a class outside of the form was updating a textbox.

		public void updateText(string text)
		{
			textBox1.Text = text;
			textBox1.Invalidate();
		}



Sir, thanks to give me an answer..
I modified my code according to your reply....
But it is not working.
Nothing happens to the textbox!!!!
Is there any other problem with the code?
Was This Post Helpful? 0
  • +
  • -

#4 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 942
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Accessing GUI from another class

Posted 17 August 2009 - 02:24 PM

Have you tried modifying this method to use the Invalidate method?

		void setText(TextBox tbox,string text)
		{
			tbox.Text = text;
			tbox.Invalidate();
		}


Was This Post Helpful? 0
  • +
  • -

#5 khedarnath  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-January 09

Re: Accessing GUI from another class

Posted 17 August 2009 - 10:43 PM

[quote name='SixOfEleven' date='17 Aug, 2009 - 01:24 PM' post='738314']

I modified the code as u said, but still its not working.
Here is the modified code. Am just a beginner so there may be simple mistakes :)
//in class for form1
public void updateText(TextBox tbox, string text)
		{
			tbox.Text = text;
			tbox.Invalidate();
		}

//in class for connection
		Form1 f = new Form1();
		 f.updateText(f.textBox1, msg);



Was This Post Helpful? 0
  • +
  • -

#6 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 942
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: Accessing GUI from another class

Posted 18 August 2009 - 05:04 PM

I've been looking through your code a little more carefully. I believe I have found what you are doing wrong. When you create a new ConnectionThread object you are creating a new instance of Form1. What you want to do is pass the current instance of the form in the constructor as well as the TcpListener object. To start with, in Form1 you have the method. You will want to pass in the instance of Form1 using this.

		void runserv()
		{
			
			TcpListener sev = new TcpListener(IPAddress.Any, 5555);
			sev.Start();
			Console.WriteLine("Waiting for connection");
			while (true)
			{
				while (!sev.Pending())
				{
					Thread.Sleep(1000);
				}
				ConnectionThread newconn = new ConnectionThread(sev, this);
			}
		}

		// make sure to change this as well
		public void updateText(string text)
		{
			textBox1.Text = text;
			textBox1.Invalidate();
		}




Now you will have to make a modification to the ConnectionThread class to reflect the change you made in passing in the instance of Form1. You will want to not make an new instance of Form1 and change the constructor to take an instance of Form1.

	class ConnectionThread
	{
		TcpListener threadListener;
		// This is the first change
		Form1 f; 
		delegate void setTextCallback(TextBox tbox, string text);
		string makeSysMsg(int msgType, string msg)
		{
			return Convert.ToString(msgType) + msg;
		}

		// This has been changed as well
		public ConnectionThread(TcpListener lis, Form1 form1)
		{
			f = form1;
			threadListener = lis;
			Thread newthread = new Thread(new ThreadStart(HandleConnection));
			newthread.Start();
		}
		void setText(TextBox tbox,string text)
		{
			tbox.Text = text;
			tbox.Invalidate(); // you should make sure and do this but I don't see you using this in your code anywhere
		}
		public void HandleConnection()
		{
			byte[] data = new byte[1024];
			if (f.textBox1.InvokeRequired)
			{
				setTextCallback fun = new setTextCallback(setText);
				this.f.Invoke(fun, new object[] { f.textBox1, "khedar" });
			}
			int myId = 0;
			int UPDATE_LIST = 2;

			//accept client
			TcpClient client = threadListener.AcceptTcpClient();
			NetworkStream ns = client.GetStream();
			NetworkStream pairns = null;

			//send welcome message
			string mesg ="1Welcome";
			data = Encoding.ASCII.GetBytes(mesg);
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			//recieve machineName
			data = new byte[1024];
			int recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineName =  ASCIIEncoding.ASCII.GetString(data).Trim('\0');

			//recieve machineIP
			/*data = new byte[1024];
			recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineIP = ASCIIEncoding.ASCII.GetString(data);*/
			
			//add to list and refresh listbox
			user curuser=new user(client,machineName,shared.onLineusers.Count+1);
			shared.onLineusers.Add(curuser);
			refreshList();

			//send getCB msg
			 mesg= "2getCB";
			 data = Encoding.ASCII.GetBytes(mesg); ns.Flush();
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			while (true)
			{
				data = new byte[1024];
				recv = 0;
				try
				{
					recv = ns.Read(data, 0, data.Length);
					int a = 19;
				}
				catch (System.IO.IOException r) {MessageBox.Show(r.ToString()); }
				//Console.WriteLine(Encoding.ASCII.GetString(data));
				
				if (recv == 0)
					break;
				string msg = ASCIIEncoding.ASCII.GetString(data);
				int msgType = Convert.ToInt32(msg[0]) - 48;
				if ((msgType == 1) | (msgType == 2) | (msgType == 3) | (msgType == 4) | (msgType == 5))
				{

					msg = msg.Substring(1);
				}
				switch (msgType)
				{
					case 2://recieve the clipboard text
						 //HERE IS THE PROBLEM
						f.updateText(msg);
						//f.textBox1.Text = msg;
						break;
					case 4://its a login request
						break;
					case 5://its an ordinary message
						msg = makeSysMsg(5, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
					case 6://its a chat message
						msg = makeSysMsg(6, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
				}
			}
			ns.Close();
			client.Close();
		}
		void refreshList()
		{
			f.listBox1.Items.Clear();
			for (int i = 0; i < shared.onLineusers.Count; i++)
			{
				f.listBox1.Items.Add(shared.onLineusers[i].name);			 
			}
			f.listBox1.Invalidate(); // You will probably have to do this as well
		}
	}
}


Was This Post Helpful? 1
  • +
  • -

#7 Aeternalis  Icon User is offline

  • D.I.C Regular

Reputation: 28
  • View blog
  • Posts: 291
  • Joined: 13-July 09

Re: Accessing GUI from another class

Posted 18 August 2009 - 05:27 PM

Hey, just gona jum in here for a sec.. SixofEleven seems to have it handled..

Khedarnath- do you know how to set a breakpoint in your code? If so, set a breakpoint in the

updateText()

method at the very beginning of it. That way when the code is called (if it is being called), you can inspect the data the text is being set to.. and see that it is proper;ly being set at that point. Will tell you a couple of things..

1, if you do get there and it sets the text correctly, you are looking for an overwrite at some other point in the program.

2, if you do not get there, you need to look at why the function is not getting called.. some control statement error making the code not execute.


I hope this helps.. Are you using Visual studio?

The code supplied is quite complex for a new person.. did you find the code in a tutorial or something? There is exception handling and other advanced concepts included in there..

Good luck!

AET
Was This Post Helpful? 1
  • +
  • -

#8 khedarnath  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-January 09

Re: Accessing GUI from another class

Posted 18 August 2009 - 11:14 PM




Was This Post Helpful? 0
  • +
  • -

#9 khedarnath  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-January 09

Re: Accessing GUI from another class

Posted 18 August 2009 - 11:20 PM

COOL... :) ...I have changed the code to pass the instance of form to the constructor of ConnectionThread as you mentioned. Then I run the program but it produced an exception indicating InvalidCrossThreadOperation. I made the code so that it invoke the control before doing operation on it. That is it....
It works without any error now. And I can see both the textbox and the listbox are displaying the information needed...
THANK YOU VERY MUCH SIXOFELEVEN for your great help...
Here is the modified code. I have checked it...its working properly.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace serv
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}
	   /* public void updateText(TextBox tbox, string text)
		{
			tbox.Text = text;
			tbox.Invalidate();
			//textBox1.Text = text;
		   // textBox1.Invalidate();
		}*/
		private void button1_Click(object sender, EventArgs e)
		{
			Thread server = new Thread(new ThreadStart(runserv));
			server.Start();
		}
		void runserv()
		{
			
			TcpListener sev = new TcpListener(IPAddress.Any, 5555);
			sev.Start();
			Console.WriteLine("Waiting for connection");
			while (true)
			{
				while (!sev.Pending())
				{
					Thread.Sleep(1000);
				}
				ConnectionThread newconn = new ConnectionThread(this,sev);
			}
		}

		private void button2_Click(object sender, EventArgs e)
		{
			
		}

		private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
		{
			TcpClient cl = shared.onLineusers[listBox1.SelectedIndex].myTcp;
			NetworkStream ns = cl.GetStream();
			//send getclipboard message
			ns.Write(ASCIIEncoding.ASCII.GetBytes("2getCB"),0,"2getCB".Length);
		}
	}
	class ConnectionThread
	{
		TcpListener threadListener;
		Form1 guiForm;
		delegate void setListCallback(ListBox lbox);
		delegate void setTextCallback(TextBox tbox, string text);
		string makeSysMsg(int msgType, string msg)
		{
			return Convert.ToString(msgType) + msg;
		}
		
		public ConnectionThread(Form1 f, TcpListener lis)
		{
			guiForm = f;
			threadListener = lis;
			Thread newthread = new Thread(new ThreadStart(HandleConnection));
			newthread.Start();
		}
		void setText(TextBox tbox,string text)
		{
			tbox.Text = text;
		}
		public void HandleConnection()
		{
			byte[] data = new byte[1024];
			int myId = 0;
			int UPDATE_LIST = 2;

			//accept client
			TcpClient client = threadListener.AcceptTcpClient();
			NetworkStream ns = client.GetStream();
			NetworkStream pairns = null;

			//send welcome message
			string mesg ="1Welcome";
			data = Encoding.ASCII.GetBytes(mesg);
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			//recieve machineName
			data = new byte[1024];
			int recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineName =  ASCIIEncoding.ASCII.GetString(data).Trim('\0');

			//recieve machineIP
			/*data = new byte[1024];
			recv = 0;
			try
			{
				recv = ns.Read(data, 0, data.Length);
			}
			catch (System.IO.IOException r) { }
			string machineIP = ASCIIEncoding.ASCII.GetString(data);*/
			
			//add to list and refresh listbox
			user curuser=new user(client,machineName,shared.onLineusers.Count+1);
			shared.onLineusers.Add(curuser);
			refreshList();

			//send getCB msg
			 mesg= "2getCB";
			 data = Encoding.ASCII.GetBytes(mesg); ns.Flush();
			try
			{
				ns.Write(data, 0, data.Length);
			}
			catch (System.IO.IOException e) { }

			while (true)
			{
				data = new byte[1024];
				recv = 0;
				try
				{
					recv = ns.Read(data, 0, data.Length);
				}
				catch (System.IO.IOException r) {MessageBox.Show(r.ToString()); }
				
				if (recv == 0)
					break;
				string msg = ASCIIEncoding.ASCII.GetString(data);
				int msgType = Convert.ToInt32(msg[0]) - 48;
				if ((msgType == 1) | (msgType == 2) | (msgType == 3) | (msgType == 4) | (msgType == 5))
				{

					msg = msg.Substring(1);
				}
				switch (msgType)
				{
					case 2://recieve the clipboard text
						if (guiForm.textBox1.InvokeRequired)
						{
							setTextCallback set = new setTextCallback(setText);
							guiForm.Invoke(set, new object[] { guiForm.textBox1, msg });
						}
						break;
					case 4://its a login request
						break;
					case 5://its an ordinary message
						msg = makeSysMsg(5, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
					case 6://its a chat message
						msg = makeSysMsg(6, msg);
						pairns.Write(ASCIIEncoding.ASCII.GetBytes(msg), 0, msg.Length);
						break;
				}
			}
			ns.Close();
			client.Close();
		}
		void setList(ListBox lbox)
		{
			lbox.Items.Clear();
			for (int i = 0; i < shared.onLineusers.Count; i++)
			{
				lbox.Items.Add(shared.onLineusers[i].name);
			}
		}

		void refreshList()
		{

			if (guiForm.listBox1.InvokeRequired)
			{
				setListCallback setlis = new setListCallback(setList);
				guiForm.listBox1.Invoke(setlis,new object[] {guiForm.listBox1});
			}
		}
	}
}



Was This Post Helpful? 0
  • +
  • -

Page 1 of 1