C# Windows Forms: Access Controls(Labels, Buttons) in other Classes - c#

I need to know, how I can access lables or buttons other than in my "Form1"-Class.
My Problem:
I created for example labels, buttons via the design viewer. Now I can access
them in my Form1 Class. (testlabel.Enabled == true) just for example.
What I CAN'T do: Access those labels, buttons in another class! Let's say
I have a class "second-class" and I want to have a method there, that changes
the property of a label to
`testlabel.Enabled == false`
That's not possible, because in that "second-class" it's not visible.
So, is there an obvious easy solution to make those controls accessible in other classes?

Create a method in that (Second class) which takes that component (Label or Button or whatever you want to modify) as parameter into that method.
public void disableLabel(Label inputLabel)
{
inputLabel.Enabled == false
}
Create a method like the above.
Now in the form1 class you just to need to call that method and pass your Label into that method to Disable it.
SecondClass objSecondClass = new SecondClass();
objSecondClass.disableLabel(testlabel);

Every control in a form class is created by default with its property Modifiers set to Private
If you change it to Public you could access the control instance from another class.
However this is really a bad practice to follow. Messing with the visibility of the control is dangerous and could cause very complicated bugs to resolve.
If you really need to change something in your form class then provide a public method and call this method to change the internal functionality of the target form

Related

How to access WPF control properties outside of main class

I have a 'public static' class that gets called on application startup. In this class, I'm trying to set the "IsEnabled" and "IsChecked" properties of several check-boxes. I had no problem doing this in MainWindow.xaml.cs but when I try to reference the check-boxes in my custom class, the check-box names aren't resolving in Intellisense/auto-complete. I also get the error, "The name 'cbx_NameOfMyBox' does not exist in the current context"
How can I access control properties outside of MainWindow.xaml.cs?
namespace Widget
{
public static class StartupSequence
{
public static void Begin()
{
GetDomain.Start();
cbx_GpoUpdate.IsEnabled = false;
return;
}
}
}
SUGGESTIONS:
You need to implement MVVM and bind the data.
If you are going to use static class to share data, then i would suggest using singleton class. You should not make the class static. You should make the constructor of the class as private. Then, create a static property which can return your class. (just do some google search to learn about singleton)
SOLUTION TO YOUR ISSUE (as a quick fix) :
You are doing it in the opposite direction. Main purpose of static property is that it can be accessed from anywhere in the project (provided the namespaces are properly referenced). So, instead of trying to access your control from the static class, do it the other way. In your xaml.cs (Control's code behind), like when the control is loaded or initiated or somewhere suitable, add like,
cbx_GpoUpdate.IsEnabled = StartupSequence.your_boolean_property_for_this
You need to have a boolean property in your static class to store the required data and when the control is initiated, you refer it. You can also created different other properties for different controls and in each controls' code behind you can refer them whenever they are loaded or a button is clicked or in any other event scenario.
Note: I started exactly the way you are doing it (in code behind) but after several months and projects later, i learned it the hard way that MVVM pattern is the best for WPF. Now, 3 years straight, all my projects are in MVVM. Start to learn MVVM and move to it as soon as possible. Cheers.

How to expose ALL properties of a Control in a class derived from Form?

I have class derived from Form and it contains a TableLayoutPanel and in it one Label and one Panel. When I create instance of this Form, all properties and events of controls in design editor are read-only. Is there any way how to expose whole object for editing? I know that I can expose properties one by one, but that is not the best way in case when you want all of them.
Have a look here:
Avoid Visual Inheritance
The TableLayoutPanel control does not support visual inheritance in
the Windows Forms Designer. A TableLayoutPanel control in a
derived class appears as locked at design time.
You can use internal or make a getter method / property
public Label GetLabel() => return someLabel;
or
public Label MyLabel { get { return someLabel; } }
or
internal Label someLabel;

How to use an item on form from another class C#

So i have created Windows Form Application and made a library added a reference so that i can use classes from library.
Now i have in a method that is in a class that is in that library it needs to change a pic in PictureBox so how do i get access to a pictureBox that is on form(Form1).
And also it would be nice that the method is able to get in what kind of item he is, for example in picturebox1 or picturebox2 so that it changes the pictureBox that it is called from.
But mainly how to access that pictureBox.
You can't make the class library refer to the application, as otherwise you'd have a cyclic dependency. It's hard to say exactly what you should do, but generally speaking class libraries shouldn't be interested in changing aspects of a user interface directly - that's normally a more application-specific requirement.
It's possible that what you really want is an event - the class library would publish an event, and the application would subscribe to it. The class library would then fire the event at the appropriate time, leaving the application code to handle the event by changing the picture.
Your library has a class with a method in it, with needs to get access to a PictureBox in any arbitrary Form-Object, is that right?
Let your method in the library class have a parameter of type PictureBox. Call that method from your form and pass on the PictureBox object you want to change.
you can get the reference of the Item like this:
void DoWork(ref TextBox t)
{
t.Text="Hi!";
}
Well if pictureBox is private inside the Form1 class, you can create a property to access it from the outside:
public class Form1
{
public PictureBox Pic
{
get
{
return pictureBox;
}
}
}
Then you can access it from an instance with form.Pic.

C# Using a form to load other user controls and have access to a base control or property

Currently I have a C# program with a windows form and then a user control template put onto the form. The user control template is really just used as a placeholder. I have a series of other controls which inherit from this user control template.
Each of those controls have navigation buttons like 'Continue' and 'Back' on them and each control knows which control needs to be loaded next. However what I need to figure out is an easier way to have variables that are global to these controls.
The only workaround I have is that I pass the form to each control when they are loaded and use variables inside of the form to read and write to. What would be the proper way to have each of these user control screens be built off of a base control which contained objects all of the controls could get to?
Sorry for the rambling nature of the post but I've been thinking about this problem all morning.
Here is some of the code:
Most of what I have written was based on hiding and showing the user controls so that content in the controls wouldn't be lost during navigation. I won't be needing to do that as eventually it will be loading the fields of data from a database.
Code for initially loading control from form click:
conTemplate1.Controls.Clear();
conInbound Inbound = new conInbound(this);
Inbound.Dock = DockStyle.Fill;
Inbound.Anchor = (AnchorStyles.Left | AnchorStyles.Top);
conTemplate1.Controls.Add(Inbound);
Code for Continue button inside of one of the controls:
if ((Parent.Controls.Count - 1) <= Parent.Controls.IndexOf(this))
{
UserControl nextControl = new conPartialClear();
nextControl.Dock = DockStyle.Fill;
Parent.Controls.Add(nextControl);
this.Hide();
Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
}
else
{
this.Hide();
Parent.Controls[Parent.Controls.IndexOf(this) + 1].Show();
}
The best-practice for communicating from a control to a parent is to use events, and for communicating from a parent to a control is to call methods.
However, if you don't want to or can't follow this practice, here's what I would recommend.
Each UserControl has a ParentForm property that returns the Form that contains the control. If you know that the UserControl will always be attached to MyParentForm, you just cast the ParentForm and then you can access all public controls, methods, etc.
Here's what I mean:
public class conTemplate
{
public MyParentForm MyParentForm
{
get
{
return (MyParentForm)this.ParentForm;
}
}
}
This way, you can easily access any public members of MyParentForm. Your conInbound class could have code such as this.MyParentForm.GlobalSettings.etc..., and could even have access to any public controls.
I'm not totally sure I understand your problem. It sounds like you want the user control to "do something" with it's parent form. If that's the case, you may want to consider adding events to the UC and then handle them on the form itself.
Basically, for your UC's "continue", you'll have an event that's fired when it's pressed. You'll want to handle that in your form. I'm not real sure about the syntax from memory, or I'd work something out for you code-wise. But I think that's the route you'll want to take. Think of your UC like any other windows form control. If you add a button to your form, you assign it it's event method. Do the same with the UC.
I found this and thought it may be helpful. Scroll down to where it talks about UC's and events.
http://www.akadia.com/services/dotnet_user_controls.html
Hope this helps.
EDIT after new info from OP.
You could declare a global variable inside the UC of type yourForm and then set that variable to the ParentForm at run-time, if I'm understanding you correctly.
So, inside your UC Class, you could do:
private parentFormInstance;
then inside the constructor of the UC, you could set it as such:
parentFormInstance = this.ParentForm; (or whatever the property name is).
This allows you at design-time to use:
parentFormInstance.DoSomething();
without the compiler yelling at you.
Just basic advice, but if you can go back and make it easier on yourself, even if it takes some additional time re-working things, it'd be worth it. It may save you time in the long run.

Unable to access Winforms control in a class

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
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
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.
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.
Take a look at how this could be implemented using the MVP pattern (sample code): Implementing MVC with Windows Forms
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.

Categories