I had windows form I did my code to display panel where condition but this error apeared (object refrencer.....) on panel1.Show();
public partial class Checker : Form
{
public Checker()
{
RegistryKey adobe = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe");
if (adobe == null)
{
panel1.Show();
}
}
private void OK_Click(object sender, EventArgs e)
{
}
}
Seems like you don't have an instance of your panel1.
Where is it declared? Is it a panel on a form somewhere? If so, where is your form declared?
If the code above is your form, you might want to call
InitializeComponent();
before you continue your constructor.
Related
I have a form called frmTest1 with a splitcontainer with two panels. Panel 2 should load many forms one at a time. It works fine for the first form, but the second form cant then load a third form into panel 2 of frmTest1.
Here is stripped frmTest 1 code:
namespace Project1
{
public partial class frmMain3 : Form
{
public frmMain3()
{
InitializeComponent();
}
private void btnShowTest1_Click(object sender, EventArgs e)
{
showScreen(new frmTest1());
}
public void showScreen(Control ctl)
{
while (splitContainer1.Panel2.Controls.Count > 0)
splitContainer1.Panel2.Controls[0].Dispose();
if (ctl is Form)
{
var frm = ctl as Form;
frm.TopLevel = false;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Visible = true;
}
ctl.Dock = DockStyle.Fill;
splitContainer1.Panel2.Controls.Add(ctl);
}
}
}
The second form's code is below:
namespace Project1
{
public partial class frmTest1 : Form
{
public frmTest1()
{
InitializeComponent();
}
private void btnShowTest4_Click(object sender, EventArgs e)
{
frmMain3 main = new frmMain3();
main.showScreen(new frmTest4()); //Nothing shows
}
}
}
From the research I have done it seems the solution is to use a usercontrol but having never used it before, I am struggling. Can someone please show me how to resolve this?
Please try to use a UserControl. Just change the base class of frmMain3 to "UserControl" and delete the whole "if (ctl is Form)"-part from showScreen().
Ok, am going to try and ask this without sounding dumb. I have a user form that I create dynamic textboxes inside a panel. I want to reference these textboxes or the panel from another form to send the texbox data to excel. I need to know how I can reference these controls. Thank you in advance!!
Create public properties on the user control, one for each element you want to access.
public class MyControl : UserControl
{
public string Name
{
get { return textBoxName.Text; }
}
public string Address
{
get { return textBoxAddress.Text; }
}
...
Then use those from the parent control that hosts the user control.
string name = myControl1.Name;
string address = myControl.Address;
Assume you have Form1 that dynamically adds a TextBox to panel panel1 during the load event like this:
private void Form1_Load(object sender, EventArgs e)
{
panel1.Controls.Add(new TextBox());
}
And you have Form2 from which you want to access the data on panel1. On Form2 you can add a public field to store the reference to panel1, but you can call it whatever you want. In this case, I use sourcePanel:
public partial class Form2 : Form
{
public Panel sourcePanel;
public Form2()
{
InitializeComponent();
}
}
Then you can pass the panel1 reference to any new Form2 instance when the new instance is created, for example from a button click event on Form1:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.sourcePanel = panel1;
f2.Show();
}
Then on Form2, you can access all the values in the TextBoxes with code like this:
private void Form2_Load(object sender, EventArgs e)
{
foreach (TextBox txt in sourcePanel.Controls.OfType<TextBox>())
{
System.Diagnostics.Debug.WriteLine(txt.Text);
}
}
I have 2 forms. The second form is opened from a method in the first form and I wish to be able to update the textbox that exists within that second form.
Basically I have the following code:
private void sendAllButton_Click(object sender, EventArgs e)
{
SendConsoleGUI sendOutGUI = new SendConsoleGUI();
sendOutGUI.Show();
sendOutGUI.sendConsoleTextBox.Text = "Test";
}
When I press the button the second form (SendConsoleGUI form) opens but "Test" is never added to its textbox.
Am I doing something wrong here?
You need to use invoke method.
sendOutGUI.Invoke((MethodInvoker) delegate { sendOutGUI.sendConsoleTextBox.Text = "Test"; });
public partial class ParentForm : Form
{
public ParentForm()
{
InitializeComponent();
}
private void sendAllButton_Click(object sender, EventArgs e)
{
SendConsoleGUI sendOutGUI = new SendConsoleGUI("Test");
sendOutGUI.Show();
}
}
public partial class ChildForm : Form
{
public ChildForm(string str)
{
InitializeComponent();
sendConsoleTextBox.Text = str;
}
}
This will work for you if you only wish to update it when the ChildForm is initially created.
In my project I have a Settings form and a Main form.
I'm trying to call the Main form's MasterReset function from the Setting form, but nothing happens.
The Master form's Masterreset function looks like this.
public void MasterReset()
{
DialogResult dialogResult = MessageBox.Show("Are you sure you want to perform master reset? All settings will be set to default.", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string phonebook_path = path + "\\Phonebook\\Contacts.xml";
XmlDocument xDoc = new XmlDocument();
xDoc.Load(phonebook_path);
XmlNode xNode = xDoc.SelectSingleNode("People");
xNode.InnerXml = "";
xDoc.Save(phonebook_path);
listView1.Clear();
people.Clear();
}
else if (dialogResult == DialogResult.No)
{
return;
}
}
And I'm accessing it from the Settings form like this
private void btn_MasterReset_Click(object sender, EventArgs e)
{
Main f1 = new Main();
f1.MasterReset();
}
Why am I not seeing any results?
Do you know what composition over inheritance is?
In the form where you have MasterReset you should do something like this:
Llet's suppose that in your second form you have something like this, and let's suppose your "mainform" will be called "MasterForm".
public partial class Form1 : Form
{
private MasterForm _masterForm;
public Form1(MasterForm masterForm )
{
InitializeComponent();
_masterForm = masterForm;
}
}
Here's the code in your masterForm Class:
private void button2_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1(this);
}
Here's in your form1:
private void btn_MasterReset_Click(object sender, EventArgs e)
{
_masterForm.MasterReset();
}
Hope this helps!
This worked for me: In your Program class, declare a static instance of Main (The class, that is) called Form. Then, at the beginning of the Main method, use Form = new Main(); So now, when starting your app, use
Application.Run(Form);
public static Main Form;
static void Main() {
Form = new Main();
Application.Run(Form)
}
Now, calling a function from another form is simple.
Program.Form.MasterReset(); //Make sure MasterReset is a public void
namespace F1
{
// Method defined in this class
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//This method I would like to call in other form
public void function()
{
MessageBox.Show("Invoked");
}
// opening the new form using button click
private void OpenNewForm_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
}
}
// This is second form
public partial class Form2: Form
{
public Form2()
{
InitializeComponent();
}
// on button click Form1 method will be called
private void button1_Click(object sender, EventArgs e)
{
var mainForm = Application.OpenForms.OfType<Form1>().Single();
mainForm.function();
}
}
}
There are multiple solutions possible. But the problem itself arise from the bad design. If you need something to be accessed by many, then why should it belong to someone? If, however, you want to inform something about anything, then use events.
Your mistake is what you are creating another instance of form1, thus MasterReset is operating with form, which is not even shown.
What you can do:
Make (as Ravshanjon suggest) a separate class to handle that MasterReset (and maybe something else). But also add to it an event. form1 and form2 can both subscribe to it and whenever either of them call MasterReset - both will react.
Create form dependency (as BRAHIM Kamel suggested): when you create form2, then pass to it form1 instance (as constructor parameter or by setting public property), to be able to call public non-static methods of form1.
As a quick, but relatively legimate solution, make this method static:
private static Form1 _instance;
public Form1()
{
InitializeComponents();
_instance = this;
}
public static void MasterReset()
{
// alot of code
_instance.listView1.Clear();
// alot of code
}
this way you can call MasterReset from any other form like this Form1.MasterReset(). Disadvantage of this method is what you can not have more than one instance of form2 (which is more likely anyway).
I understand your problem, you can declare your function as public static void(also listView1 and people should be static too). Then when you want to call to like this:
private void btn_MasterReset_Click(object sender, EventArgs e)
{
Main.MasterReset();
}
I have a program that has a parent form which then creates a child form. Upon clicking the updateButton within the child form, I want the searchButton within the parent form to fire.
However I get an error for protection reasons. I have tried setting everything Public just to see, still wont work for me.
Error 1 'SalesSystem.SystemForm.searchButton' is inaccessible due to
its protection level SalesSystem\UpdateForm.cs 111 20 SalesSystem
This is what I have so far.
Parent Code
namespace SalesSystem
{
public partial class SystemForm : Form
{
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
}
Child Code
namespace SalesSystem
{
public partial class UpdateForm : Form
{
public UpdateForm(string selectedPerson, string dbdirec, string dbfname)
{
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
SystemForm parent = (SystemForm)this.Owner;
parent.searchButton.PerformClick();
this.Close();
}
}
}
Your searchButton button control is set to private by default in WinForm. You've said you set everything to public but I assume you mean you've set everything in the code you've posted to public. There are a few ways to fix this. The direct fix would be to simply go to Visual Studio designer, select the button, and set its Modifier property to internal or public.
However, it seems you're closing your form straight after so I'd just have my parent form subscribe to the FormClosing event of the form.
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.FormClosing += (s, o) =>
{
//your code for what the parent class should do
};
upForm.ShowDialog(this);
If you're not closing the form then you can create your own event handler that your parent form subscribes to.
You have 2 options:
create a public void search() method in your parent form. Then, instead of accessing the the button on the parent form and invoking its click event, you run the search code directly. The new method is not tied to a GUI element and accessing it from a different form is no problem.
The better solution is to create a delegate. A delegate is an execution target that will be assigned at run time. The parent form still has a public void search() method. And when it creates the child form, it will pass the name of that function as parameter. The child form has no knowledge about the parent form (as opposed to the first option where the child MUST know that there is a method called search()). When it is time to inform whoever created the child form, the delegate is called. This is a small example:
public partial class SystemForm : Form
{
public delegate void dSearch();
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
search();
}
private void search()
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname, search);
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
}
And the child form:
public partial class UpdateForm : Form
{
private SystemForm.dSearch _target;
public UpdateForm(string selectedPerson, string dbdirec, string dbfname, SystemForm.dSearch target)
{
_target = target;
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
_target();
this.Close();
}
}
You should use the "Model View Controller" or "Model View Presenter" pattern to approach this kind of thing.
Each form should only be concerned with displaying its contents to the user. When it comes to responding to UI events such as button clicks, each form (i.e. each "View") should simply raise an event which informs the controller/presenter that something has happened.
The controller/presenter should then respond appropriately. Then the logic that wires together different forms (such as the parent and child forms in your example) is encapsulated in the Controller class. Such logic does not really belong in either of the forms.
I wrote an example that demonstrates a simple design to do this sort of thing in another answer some time ago. Rather than copy/paste it all here, I'll just give you a link to it:
How to make Form1 label.text change when checkbox on form2 is checked?
You'll have to scroll down to see my answer. It's broadly similar to what you're doing; hopefully it will make sense to you! Follow the instructions to make a test application and run it to see what happens.
I'm tired and might be missing something but that is correct behaviour.
Your child form does not directly inherit from your parent form.
Your parent form has a protected level, so only it and classes that extend it can access the method.
2 solutions:
Change your child form to:
public partial class UpdateForm : SystemForm
Change method to public
public void searchButton_Click(object sender, EventArgs e)
You could expose a Search Event from your UpdateForm and subscribe to this event in the SystemForm
namespace SalesSystem
{
public partial class SystemForm : Form
{
public SystemForm()
{
InitializeComponent();
}
protected void searchButton_Click(object sender, EventArgs e)
{
//search code
}
private void updateButton_Click(object sender, EventArgs e)
{
try
{
UpdateForm upForm = new UpdateForm(resultBox.SelectedItems[0].Text, dbdirec, dbfname);
upForm.OnSearch += Search;
upForm.ShowDialog(this);
}
catch (Exception)
{
//
}
}
private void Search(string searchParameter)
{
....
}
}
namespace SalesSystem
{
public delegate void SearchEventHandler(string searchParameter);
public partial class UpdateForm : Form
{
public event SearchEventHandler OnSearch;
public UpdateForm(string selectedPerson, string dbdirec, string dbfname)
{
InitializeComponent();
}
private void updateButton_Click(object sender, EventArgs e)
{
//do stuff
OnSearch("SearchThis");
this.Close();
}
}
}