I want to either enable or disable a button from another file,what should I do?
This is the form class declaration:
public partial class Form1 : Form
I tried with
Form.btnName.enabled = false/true
but there's no btnName member.
Thanks in advance!
Simply expose a public method:
public void EnableButton(bool enable)
{
this.myButton.Enabled = enable;
}
Correction:
public void EnableButton()
{
this.myButton.Enabled = true;
}
You need to expose the btnName member to other classes by making it public or using a property of sorts. For example add the following code to Form1
public Button ButtonName { get { return btnName; } }
Now you can use form.ButtonName for any instance of Form1
I really suggest to read more information on how forms fit in .net. You have a couple issues in that sample code "Form.btnName.enabled = false/true"
Your form is called Form1, it inherits from Form.
Forms are instances, in fact you can have different form instances in an application belonging to the same class.
Because of the above, it would not make sense to access Form1.btnName. You have to do it through the specific instance.
Form's controls are not public by default, define a method for that.
Windows forms projects, usually have a main that runs the form. There you can access the form instance and hand it to something else in the app.
The above answers the specific question. Note that there are multiple ways to achieve different scenarios, and what you really want to do might not need the above approach.
This is because by default, the controls on a form are not public (unlike in VB6 which all controls were exposed publicly).
I believe you can change the visibility accessor in the designer to public, but that's generally a bad idea.
Rather, you should expose a method on your form that will perform the action on the button, and make that method accessible to whatever code you want to call it from. This allows for greater encapsulation and will help prevent side effects from occurring in your code.
You'll have to specify it on your specific instance of Form1.
Ie: If you have something like Form1 myForm = new Form1(...);, then you can do myForm.btnName.Enabled = false;
This will also require that btnName is public. It would be "better" to make a property or accessor to retrieve it than directly provide public access to the, by default, private button field member.
You need to add a public property, or method to set the button.
public void DisableBtnName()
{
this.btnName.Enabled=false;
}
public Button BtnName
{
get { return this.btnName;}
}
In Form1, create a object for external class(add button name in the parameter)
Class1 obj_Class1 = new Class1(btnName);
In Class1 , create a private button
private System.Windows.Forms.Button btnName;
In Class1 Construct
public Class1(System.Windows.Forms.Button btnName)
{
this. btnName = btnName;
}
then you can access your button like,
btnName.enabled = false/true;
Related
I have a problem. I am trying to access a panel in a user control.When I access it in a form it works. Earlier on I did this.
I accessed a panel in a form from a user control and it worked. Below is the code I used:
Form1 form = Application.OpenForms.OfType<Form1>().FirstOrDefault();
form.Panel1.Controls.Clear();
ManageControl user = new ManageControl();
form.Panel1.Controls.Add(user);
But when I try to use the very same concept in a user control it does not work.
It throws a null error: Object reference not set to an instance of an object.
Below is the code:
//this is in ManageControl.cs
public Panel Panel2
{
get { return panelmanage; }
}
//this is in another userControl.Trying to access panelImage
ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
form.Panel2.Controls.Clear();//it throws the error here
ReportControl user = new ReportControl();
form.Panel2.Controls.Add(user);
What am I doing wrong because I am using the same concept?
EDIT:
This is my ManageControl.cs
public partial class ManageControl : UserControl
{
public ManageControl()
{
InitializeComponent();
}
public Panel Panel2
{
get { return panelmanage; }
}
This is how I try to access it in BookingListControl
public partial class BookingListControl : UserControl
{
ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
public BookingListControl()
{
InitializeComponent();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
ReportControl user = new ReportControl();
form.Panel2.Controls.Add(user);
}
ManageControl is a UserControl not a Form. Thus, when you look for open forms of type ManageControl, you get nothing (no surprises here). Then, we you call FirstOrDefault it returns null (since there were no matching elements in the empty collection), and your next line blows up.
This approach is doomed from the start, because even if you had a whole bunch of forms overlaying each other and could make it work (bad idea), it would break once you had two ManageControl objects and needed to access the second.
Instead, first ask yourself, "Why do my UserControl objects need to access each other?". This is an important question, because in general UserControls are independent. They likely have methods to give data back to their parent, but thats it. They certainly don't interact with other UserControls.
If you decide that you really need this dependency, then I would pass the parent Form object to both UserControls and have a public property on the Form that allows them to see the other UserControl. From here you can access it normally (without needing any OpenForms nonsense). Honestly though, this is a massive code smell and it sounds like the whole design should be looked at to see where you have dependencies that could be removed.
To do this you need to expose the ManageControl on the form:
public class ParentForm : Form
{
public ManageControl Manager { get { return manageControlInstance; } }
...
}
Then access it in your child control. The easiest way would be through the Parent property, but you could pass it on the constructor or an Init function as well.
public class ChildControl : UserControl
{
private void SomeFunction()
{
(Parent as ParentForm).Manager.Panel2.Controls.Add(new ReportControl());
}
}
The code's pretty ugly, and I wouldn't recommend it (its also not safe if you put the ChildControl into anything other than a ParentForm). That being said it would work.
Assuming that the NullReferenceException occurred based on accessing the "Panel2" property, your issue is that "panelmanage" is null. Is the code that finds and populates "form.Panel2" in a form or control constructor? If so, try restructuring it to run after ManageControl is fully initialized - perhaps by putting it into a Loaded event.
I have a multi-page program which changes its displayed elements by changing its visibility, which is written in the mainForm class(renamed from Form1) . Now as my program is getting more and more complicated I was thinking to make some kind of an external class in wich all these states would be changed becouse i have 26 text boxes and 3 options of displaying them which means I have 78 lines of textBox1.visibility = true; lines.
I have tried creating a class and changing the modifiers of all the textboxes to public and created an instance of form1 in my interfaceClass (MainForm mainform = new MainForm();) but this does totally not change anything to my form at all although no syntax or runtime errors happen.
I just want maybe some suggestions on how this can be realized if it can be at all.
You don't need a separate class for this; just write a single method in your form called CheckVisibility() and call that wherever you need to make sure your controls are shown or hidden properly. Include all of the necessary conditions and show/hide changes in that method.
Set the control to public in the designer:
public System.Windows.Forms.Button button1;
Create a new class and for example rename it to exampleClass
public class exampleClass
{
public static Form1 frm;
public static void HideButton()
{
frm.button1.Visible = false;
}
}
Add this after Form1 InitializeComponent:
exampleClass.frm = this;
Now you can hide the button from anywhere you want:
exampleClass.HideButton();
How does one access WinForm controls such as ProgressBar properties from another class?
Please see my code below. I know this might not be the best option to expose WinForm class and its members as public but I am trying to clear the concept at this point.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
Class1 c = new Class1();
c.loop();
}
public void PBSetup()
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
}
public void PBUpdate(int recno)
{
progressBar1.Value = Class1.recno;
}
}
}
namespace WindowsFormsApplication1
{
class Class1
{
public static int recno;
public void loop()
{
//How do I access Form1.PBSetup()??
for (recno = 0; recno <= 100; recno++)
{
//How do I access Form1.PBUpdate(recno)??
}
}
}
}
You do not want your business logic (your class) interacting with your UI (your form). The business logic should be agnostic of the presentation layer.
If you want the form to respond to things that happen inside the class, you could consider exposing an Event inside the class that the form could subscribe to, much like it would subscribe to a button's click event. The class instance could fire off the event completely unaware of who might be listening, and any subscribers would be notified.
This looks like a big time code smell :).
You would need an instance of Form1 inside of Class1 in order to PBUpdate.
Something tells me what you are doing is just not right.
Explain what you are trying to do and we can help. Otherwise there is no way to access PBUpdate unless you either made it a static function where you could call it like Form1.PBUpdate() or you had an instance of Form1 within your class Class1
You can change the access modifiers of the progress bar from private to Internal or public , you can do this operation from properties pane .
Keep in mind that you have to pass to the second class the instance of the form and then you can change the value of the progress bar directly from the second class.
However is a tricky solution, the best should be keep the presentation layer implementation separated and work with an event.
I do not recommend to use this method, for simple reason as mentioned here by one of the comments. But if you really want to access that form control, here is how:
1) Select that control and set its access modifier to internal.
2) Assume your form id is "Form1" and control id is "control1"
Inside your method:
Form1 form = (Form1)Application.OpenForms["Form1"];
// form.control1 should now be available.
I have created a forms application which uses a TabControl. For each tab I want to place a single UserControl (created in the same project) which contains all the other controls. However, I will need to pass some information from the primary form to the UserControl for it to work property with events, methods, etc. How can/should I do this?
I tried creating a constructor with parameters but then Designer fails and I have to go in and delete out the added UserControl references.
Thanks!
The constructor parameter is the correct method. However, there must still be a default constructor in order for the Designer to be able to construct (and draw) a copy of the object.
My usual workaround is to put a clause in the default constructor, checking to see that we are in "design mode" and throwing an exception if not:
public class MyForm: Form
{
public MyForm()
{
if(!DesignMode) throw new InvalidOperationException("Cannot use default constructor in production code");
}
public MyForm(MyDependency dependent)
{
...
}
}
you can pass information by a function that created in usercontrol.cs file.
for example in usercontrol.cs
public string name;
public void SetName(string pname)
{
this.name = pname;
}
or maybe you want to change button name
Button mybutton = new Button();
public void SetButtonName(string btname)
{
this.mybutton.Text = btname;
}
Now you can call these functions in your mainform.cs
Myusercontrol usc = new Myusercontrol();
usc.SetName("this is string for 'name' string");
usc.SetButtonName("this is string for button text");
Try creating your constructor, but also creating a default parameterless constructor.
Take a look at this question
I have a form that has a public property
public bool cancelSearch = false;
I also have a class which is sitting in my bll (business logic layer), in this class I have a method, and in this method I have a loop. I would like to know how can I get the method to recognise the form (this custom class and form1 are in the same namespace).
I have tried just Form1. but the intellisense doesn't recognise the property.
Also I tried to instantialize the form using Form f1 = winSearch.Form1.ActiveForm; but this too did not help
Any ideas?
When you are calling the business logic that needs to know the information pass a reference of the form to the method.
Something like.
public class MyBLClass
{
public void DoSomething(Form1 theForm)
{
//You can use theForm.cancelSearch to get the value
}
}
then when calling it from a Form1 instance
MyBlClass myClassInstance = new MyBlClass;
myClassInstance.DoSomething(this);
HOWEVER
Really you shouldn't do this as it tightly couples the data, just make a property on your BL class that accepts the parameter and use it that way.
I think you should look at how to stop a workerthread.
I have a strong feeling that you have a Button.Click event handler that runs your business logic and another Button.Click that sets your cancelSearch variable. This won't work. The GUI thread which would run your business logic, won't see the other button being clicked. If I'm right you should very much use a worker thread.
Your question is really not clear. You might want to edit it.
Advice
The form shouldn't pass to your business logic layer...
Solutions to your problem
BUT if you really want to (BUT it's really not something to do), you need to pass the reference. You can do it by passing the reference in the constructor of your class, or by a property.
Method with Constructor
public class YourClass
{
private Form1 youFormRef;
public YourClass(Form1 youFormRef)
{
this.youFormRef = youFormRef;
}
public void ExecuteWithCancel()
{
//You while loop here
//this.youFormRef.cancelSearch...
}
}
Method with Property
public class YourClass
{
private Form1 youFormRef;
public int FormRef
{
set
{
this.youFormRef = value;
}
get
{
return this.youFormRef;
}
}
public void ExecuteWithCancel()
{
//You while loop here
//this.youFormRef.cancelSearch
}
}
As the other (very quick) responses indicate, you need to have an instance variable in order to get your intellisence to show you what you need.
Your app by default does not have a reference to the main form instance, if you look at your program.cs file you will see that the form is constructed like so...
Application.Run(new Form1());
so you have a couple options, you could create a global var (yuck) and edit your program.cs file to use it..
Form1 myForm = new Form1();
Application.Run(myForm);
Pass a reference to the business object from your running form like some others have suggested
myBusinessObj.DoThisThing(this);
or find your form in the Application.OpenForms collection and use it.