6 Replies - 3780 Views - Last Post: 26 April 2008 - 12:01 PM Rate Topic: -----

#1 nbarten  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 162
  • Joined: 30-April 07

Accessing data in a Class object from your GUI

Post icon  Posted 26 April 2008 - 07:17 AM

Maybe this is a dumb question... but i actually don't know how to access objects from the GUI i made with visual studio 2008 from another class.

Let's say i have this code:

Form1.cs:

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;

namespace ChatzyClient
{
	public partial class MainForm : Form
	{
		public MainForm()
		{
			InitializeComponent();
		}
	}
}


Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace ChatzyClient
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			ClientEngine myClient = new ClientEngine();

			Thread engineThread = new Thread(new ThreadStart(myClient.StartEngine));

			// start de engineThread
			engineThread.Start();

			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			MainForm mainform = new MainForm();
			Application.Run(mainform);
			
		}
	}
}


ClientEngine.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ChatzyClient
{
	class ClientEngine
	{
		public void StartEngine()
		{
			while (true)
			{
				Console.WriteLine("test");
			}
		}
	}
}


So, you don't see it, but i have a few TextBox's like txtMonitor and txtTextInput. In form1.cs i can access the methods of those objects easily of course (like the method txtTextInput.Text) but now my question: how can i access them in the class ClientEngine?

Is This A Good Question/Topic? 0
  • +

Replies To: Accessing data in a Class object from your GUI

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4337
  • View blog
  • Posts: 12,137
  • Joined: 18-April 07

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 08:25 AM

No this isn't a silly question. This is actually a common problem with people fairly new or still learning object oriented principles. Often times people want a class to access the interface elements. This isn't right.

You should never want to tie an object that does something separately to an interface because then it makes the class dependent on that interface. You couldn't then take ClientEngine.cs out of your project and use it in another project without having to create all the controls of your form again in the new project. This binds the class to the interface in a tightly coupled fashion... which is bad for maintainability and reuseability.

What if you later decide to rename your controls or remove the control altogether? You would be forced to go back into the ClientEngine class code and rewrite parts of it. Introducing bugs accidentally along the way.

Instead what you should be thinking is how do I create an instance of my class on the form, use its methods and properties to get information and display that information to the controls on my form? This would be the form USING instances of your object. Your object itself is unaware of the interface or where the data it returns is heading. It is focusing on its job of returning accurate information to a caller.

So for instance... instead of ClientEngine finding the control txtMonitor and sending it the text "test" it should have a public method or property that returns "test" when called. Then in your form, you would...

ClientEngine ce = new ClientEngine();
txtMonitor.text = ce.getTestText();



Here we are creating an instance of the object and asking it for the "test" text we put in a method called "getTestText". What this does for us is that A.) We could essentially have multiple ClientEngine classes if we wanted B.) Makes ClientEngine loosely coupled to the interface so we could rip out the clientEngine class and use it in other projects "as is" and C.) Allows clientEngine class to focus on not sending info to specific form controls, but instead returning the correct information to a caller it knows nothing about. D.) Since it is loosely coupled, we could create another class (be it a wrapper class or just another class) that could call ClientEngine for info without needing to modify ClientEngine. This other class may not be related to the GUI interface at all, thus writing to controls is invalid.

I hope I am getting the point across. Great question. :)
Was This Post Helpful? 0
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5832
  • View blog
  • Posts: 12,686
  • Joined: 16-October 07

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 09:43 AM

As mentioned, tightly coupling objects is often seen as a bad practice. However, loading the rendering layer with a lot of worker code can also be a bad practice. Another approach is to make the elements of the form that need to be updated transparent and then use some kind of controller for the heavy lifting.

Let's assume ChatzyClient contains the object txtTextInput. That object is private, which is good, don't change that. However, we want the value in that box to be externally manipulated. So we "expose" the property out private object with a public property.

namespace ChatzyClient {
	public partial class MainForm : Form {
		// ...
		public string TextInput {
			get { return this.txtTextInput.Text; }
			set { this.txtTextInput.Text = value; }
		}
		// ...
	}
}



Now external code can mess with that value. However, in order to mess with it, they need to have it.

namespace ChatzyClient {
	class ClientEngine {
		// form reference holder
		private MainForm mainForm;
		
		// 
		public ClientEngine(MainForm mainForm) {
			this.mainForm = mainForm;
		}
		
		// expose the reference we were constructed with
		public ChatzyClient.MainForm MainForm { get { return this.mainForm; } }
		
		// methods we wrote to play with the form
		public void DoSomething() {
			this.mainForm.TextInput = "Hi Mom";
		}
	}
}



A word of warning. There are some issues with Forms and cross threading. Seriously look into the System.Windows.Forms.Timer class if you want to do threading on forms.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#4 nbarten  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 162
  • Joined: 30-April 07

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 09:56 AM

Thank you for your answers.

And yes, it often confuses me if i code in C# with an already made GUI in Visual Studio 2008. It creates automatically already a program.cs, which has the Main method, and the main method creates a new instance of a mainform which runs as the main thread...

I used to program in Java first, and then it was basically like this: create the first class with the method main in it, and create from there other objects of classes to use the functions/methods it have...

So now with the automatically events made in C# (like click on a button, etc) should i work from the mainform class?

Hope you understand me, my english isn't very good. :P
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5832
  • View blog
  • Posts: 12,686
  • Joined: 16-October 07

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 10:47 AM

You can always change the generated code! You can even write and compile code from text files, if you like. Think of the generated code as a guide, not the law. I often write event listeners by hand; the Timer is a good example. Sometimes I let the GUI make the structure for me.

You would normally handle a button click or similar event in the form that contains the button. However, it's not required. If an external object needs to know about the click, you can expose it with custom public code, or make the button public.

Having the Program.cs launch your main form is a best practice and an improvement over prior versions of Visual Studio. You can certainly manipulate what's there, if you like. Here's an example of exposing a button click.

public partial class MainForm : Form {
	public event System.EventHandler SomethingHappend;

	private void button1_Click(object sender, EventArgs e) {
		if (SomethingHappend != null) {
			SomethingHappend(this, new EventArgs());
		}
	}
}

static class Program {
	[STAThread]
	static void Main() {
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);
		
		MainForm mainform = new MainForm();
		mainform.SomethingHappend += new EventHandler(mainform_SomethingHappend);
		Application.Run(mainform);
	}
	
	static void mainform_SomethingHappend(object sender, EventArgs e) {
		MessageBox.Show("Hey, something happened!");
	}
}



No worries about language, your English is infinitely better than my Frisian. ;)
Was This Post Helpful? 0
  • +
  • -

#6 Jayman  Icon User is offline

  • Student of Life
  • member icon

Reputation: 418
  • View blog
  • Posts: 9,532
  • Joined: 26-December 05

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 11:48 AM

Excellent question, nbarten.

Those are fantastic responses, baavgai and Martyr2. I am going to Feature this topic on the front page. I am sure there are a lot more new programmers that are wondering the very same thing.

Good job!

I am also editing the title to make it more descriptive to the subject matter.

**edit: I see Martyr2 already has already blogged on this very subject. No doubt prompted by the question. :^:

So here is a link to his blog for those that want to read up on it. Martyr2's Blog: Avoid Tying Classes to Your Forms
Was This Post Helpful? 0
  • +
  • -

#7 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4337
  • View blog
  • Posts: 12,137
  • Joined: 18-April 07

Re: Accessing data in a Class object from your GUI

Posted 26 April 2008 - 12:01 PM

I appreciate the link to the blog jayman. Yeah I was looking for an entry topic and this has been like the 4th or 5th time in the last couple months I have seen such a question. So I figured I would try give more details. :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1