tags:

views:

311

answers:

4

I am currently working in a small windows forms project in C# using Visual studio 2008. I have added a custom class to the project, but in this class I am unable to access the forms controls (like listbox, textbox, buttons ) in order to programmatically change their properties.

The class file has using system.windows.forms included and all files are in the same namespace. Surprisingly, I am also unable to access the controls in the form1 class itself, unless I create a method in the class and then intellisense pops up the names of the various controls.

in the custom class however, intellisense does not show the names of the controls at all.

Appreciate if someone coudl shed some light on why this could be happening.

Thanks

+3  A: 

Encapsulation means your separate class shouldn't be talking directly to the controls. You should, instead, expose properties and methods on your (outer) Control - for example:

public string TitleText {
    get {return titleLbl.Text;}
    set {titleLbl.Text = value;}
}

For more complex operations it may be preferable to use a method; properties are fine for simple read/write for discreet values.

This provides various advantages:

  • you can, if required, abstract the details to an interface (or similar)
  • you can change the implementation (for example, use the Form's Text for the title) without changing the calling code
  • it is just... nicer ;-p
Marc Gravell
I think the problem here is that he doesn't have a reference to the form. In that case adding properties won't help. Apart from that I agree totally about not exposing the controls as public
Rune Grimstad
+3  A: 

Your class needs a reference to the form for this to work. The reason for this is that the form is not a static class so you can have multiple instances of it.

The best way of giving it the reference would probably be to pass it in the classes constructor. Then the class would have a reference to the form and could use that reference to change the controls.

An alternative option that you could use if you are 100% sure that you will have only one instance of your form open is to add a public static property to the forms class that returns the instance of the form. That property would then be available to be used in your other class.

Also, make sure that your controls are public, or better add public methods to your form that can be used to manipulate the controls indirectly.

Rune Grimstad
+3  A: 

The controls in Form1 will be private

partial class Form1
{
   //elided other good stuff 
   private System.Windows.Forms.Button button1;
}

So no, you can't access this directly from another class.

You could make it public as @abatishchev suggests (but that would be a really bad idea). A better plan would be to use properties as @Marc Gravell suggests. You would still need to pass a reference to the form to the class that you wish to have consume the properties though (as pointed out by @Rune Grimstad). You are trying to write a class in your application that directly asks the UI for data. This isn't usually considered a very good idea. The class should be entirely concerned with it's own purpose. You should design properties or events for the specific bits of data that the class needs access to and not necessarily pass it the entire form, maybe just the values that it needs to work with or change.

Hamish Smith
A: 

Take a look at how this could be implemented using the MVP pattern (sample code): http://stackoverflow.com/questions/654722/implementing-mvc-with-windows-forms/685722#685722

UPDATE: The code in the class you mention should in fact be part of the form's presenter, which has a reference to the form (through the IView interface). That is how you should be designing your UI code, not by directly accessing other Form's private parts.

Igor Brejc