How to pass value from user control to its parent form? - c#

I have a user control that will supposedly pass value to its parent form which is form1.
I used the code below.
User Control
public int _control;
public int control
{
get{return _control;}
set{_control=value;}
}
Form1 assign value to UserControl
UserControl1 uc=new UserControl1();
uc.control=1;
User Control Button_Click
var parent = this.Parent as Form1;
//MessageBox.Show(_control.ToString());
parent.userNo=_control;
Form1
public int _userNo;
public int userNo
{
get{return _userNo;}
set{_userNo=value;}
}
The problem is when i used messagebox.show, it will appear displaying 1 but when i used
parent.userNo=_control;
it returns a Null Reference Exception.
Please help!!!

That means that parent is Null. this is due to the fact that the parent is NOT an instance of the class Form1.
in fact, this cast:
this.Parent as Form1
returns NULL when this.Parent is not of the type Form1, but is another container. alternatively, if the parent is not set. to fix this, you need to get a reference of the Form to the user control or alternatively, set the parent. something like:
UserControl1 uc=new UserControl1();
uc.control=1;
uc.Parent = this;

Related

Set parent forms FormElement.TitleBar.BackColor from child form

I have a form FrmMain, which has a child form displayed within a PageView, FrmChild. I am trying to set the FrmMain's: this.FormElement.TitleBar.BackColor from FrmChild.
FrmChild
private void SetWarning() {
FrmMain.SetTitleBarColor(true);
}
FrmMain
public void SetTitleBarColor(bool warning) {
if (warning) {
this.FormElement.TitleBar.BackColor = Color.Red;
}
}
I tried setting FrmMain.SetTitleBarColor to static, but then I couldn't access the instance of the form.
The answer can be found here: answer
The correct way to update the parent form is through bubbling. Have the parent form listen for an event from the child form and have the parent update itself. Any parameters needed can be passed through the EventArgs.

Access properties of a Windows Form which was created in another Windows Form [duplicate]

How do I get access to the parent controls of user control in C# (winform). I am using the following code but it is not applicable on all types controls such as ListBox.
Control[] Co = this.TopLevelControl.Controls.Find("label7", true);
Co[0].Text = "HelloText"
Actually, I have to add items in Listbox placed on parent 'Form' from a user control.
Description
You can get the parent control using Control.Parent.
Sample
So if you have a Control placed on a form this.Parent would be your Form.
Within your Control you can do
Form parentForm = (this.Parent as Form);
More Information
MSDN: Control.Parent Property
Update after a comment by Farid-ur-Rahman (He was asking the question)
My Control and a listbox (listBox1) both are place on a Form (Form1). I have to add item in a listBox1 when user press a button placed in my Control.
You have two possible ways to get this done.
1. Use `Control.Parent
Sample
MyUserControl
private void button1_Click(object sender, EventArgs e)
{
if (this.Parent == null || this.Parent.GetType() != typeof(MyForm))
return;
ListBox listBox = (this.Parent as MyForm).Controls["listBox1"] as ListBox;
listBox.Items.Add("Test");
}
or
2.
put a property public MyForm ParentForm { get; set; } to your UserControl
set the property in your Form
assuming your ListBox is named listBox1 otherwise change the name
Sample
MyForm
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
this.myUserControl1.ParentForm = this;
}
}
MyUserControl
public partial class MyUserControl : UserControl
{
public MyForm ParentForm { get; set; }
public MyUserControl()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (ParentForm == null)
return;
ListBox listBox = (ParentForm.Controls["listBox1"] as ListBox);
listBox.Items.Add("Test");
}
}
You can use Control.Parent to get the parent of the control or Control.FindForm to get the first parent Form the control is on. There is a difference between the two in terms of finding forms, so one may be more suitable to use than the other.:
The control's Parent property value might not be the same as the Form
returned by FindForm method. For example, if a RadioButton control is
contained within a GroupBox control, and the GroupBox is on a Form,
the RadioButton control's Parent is the GroupBox and the GroupBox
control's Parent is the Form.
Control has a property called Parent, which will give the parent control. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.parent.aspx
eg Control p = this.Parent;
You can get the Parent of a control via
myControl.Parent
See MSDN:
Control.Parent
A generic way to get a parent of a control that I have used is:
public static T GetParentOfType<T>(this Control control)
{
const int loopLimit = 100; // could have outside method
var current = control;
var i = 0;
do
{
current = current.Parent;
if (current == null) throw new Exception("Could not find parent of specified type");
if (i++ > loopLimit) throw new Exception("Exceeded loop limit");
} while (current.GetType() != typeof(T));
return (T)Convert.ChangeType(current, typeof(T));
}
It needs a bit of work (e.g. returning null if not found or error) ... but hopefully could help someone.
Usage:
var parent = currentControl.GetParentOfType<TypeWanted>();
Enjoy!
According to Ruskins answer and the comments here I came up with the following (recursive) solution:
public static T GetParentOfType<T>(this Control control) where T : class
{
if (control?.Parent == null)
return null;
if (control.Parent is T parent)
return parent;
return GetParentOfType<T>(control.Parent);
}
Not Ideal, but try this...
Change the usercontrol to Component class (In the code editor), build the solution and remove all the code with errors (Related to usercontrols but not available in components so the debugger complains about it)
Change the usercontrol back to usercontrol class...
Now it recognises the name and parent property but shows the component as non-visual as it is no longer designable.
((frmMain)this.Owner).MyListControl.Items.Add("abc");
Make sure to provide access level you want at Modifiers properties other than Private for MyListControl at frmMain
If you want to get any parent by any child control you can use this code,
and when you find the UserControl/Form/Panel or others you can call funnctions or set/get values:
Control myControl= this;
while (myControl.Parent != null)
{
if (myControl.Parent!=null)
{
myControl = myControl.Parent;
if (myControl.Name== "MyCustomUserControl")
{
((MyCustomUserControl)myControl).lblTitle.Text = "FOUND IT";
}
}
}

Passing value between forms [duplicate]

How do I pass a value from a child back to the parent form? I have a string that I would like to pass back to the parent.
I launched the child using:
FormOptions formOptions = new FormOptions();
formOptions.ShowDialog();
Create a property (or method) on FormOptions, say GetMyResult:
using (FormOptions formOptions = new FormOptions())
{
formOptions.ShowDialog();
string result = formOptions.GetMyResult;
// do what ever with result...
}
If you're just using formOptions to pick a single value and then close, Mitch's suggestion is a good way to go. My example here would be used if you needed the child to communicate back to the parent while remaining open.
In your parent form, add a public method that the child form will call, such as
public void NotifyMe(string s)
{
// Do whatever you need to do with the string
}
Next, when you need to launch the child window from the parent, use this code:
using (FormOptions formOptions = new FormOptions())
{
// passing this in ShowDialog will set the .Owner
// property of the child form
formOptions.ShowDialog(this);
}
In the child form, use this code to pass a value back to the parent:
ParentForm parent = (ParentForm)this.Owner;
parent.NotifyMe("whatever");
The code in this example would be better used for something like a toolbox window which is intended to float above the main form. In this case, you would open the child form (with .TopMost = true) using .Show() instead of .ShowDialog().
A design like this means that the child form is tightly coupled to the parent form (since the child has to cast its owner as a ParentForm in order to call its NotifyMe method). However, this is not automatically a bad thing.
You can also create a public property.
// Using and namespace...
public partial class FormOptions : Form
{
private string _MyString; // Use this
public string MyString { // in
get { return _MyString; } // .NET
} // 2.0
public string MyString { get; } // In .NET 3.0 or newer
// The rest of the form code
}
Then you can get it with:
FormOptions formOptions = new FormOptions();
formOptions.ShowDialog();
string myString = formOptions.MyString;
You can also create an overload of ShowDialog in your child class that gets an out parameter that returns you the result.
public partial class FormOptions : Form
{
public DialogResult ShowDialog(out string result)
{
DialogResult dialogResult = base.ShowDialog();
result = m_Result;
return dialogResult;
}
}
Use public property of child form
frmOptions {
public string Result; }
frmMain {
frmOptions.ShowDialog(); string r = frmOptions.Result; }
Use events
frmMain {
frmOptions.OnResult += new ResultEventHandler(frmMain.frmOptions_Resukt);
frmOptions.ShowDialog(); }
Use public property of main form
frmOptions {
public frmMain MainForm; MainForm.Result = "result"; }
frmMain {
public string Result;
frmOptions.MainForm = this;
frmOptions.ShowDialog();
string r = this.Result; }
Use object Control.Tag; This is common for all controls public property which can contains a System.Object. You can hold there string or MyClass or MainForm - anything!
frmOptions {
this.Tag = "result": }
frmMain {
frmOptions.ShowDialog();
string r = frmOptions.Tag as string; }
Well I have just come across the same problem here - maybe a bit different. However, I think this is how I solved it:
in my parent form I declared the child form without instance e.g. RefDateSelect myDateFrm; So this is available to my other methods within this class/ form
next, a method displays the child by new instance:
myDateFrm = new RefDateSelect();
myDateFrm.MdiParent = this;
myDateFrm.Show();
myDateFrm.Focus();
my third method (which wants the results from child) can come at any time & simply get results:
PDateEnd = myDateFrm.JustGetDateEnd();
pDateStart = myDateFrm.JustGetDateStart();`
Note: the child methods JustGetDateStart() are public within CHILD as:
public DateTime JustGetDateStart()
{
return DateTime.Parse(this.dtpStart.EditValue.ToString());
}
I hope this helps.
For Picrofo EDY
It depends, if you use the ShowDialog() as a way of showing your form and to close it you use the close button instead of this.Close(). The form will not be disposed or destroyed, it will only be hidden and changes can be made after is gone. In order to properly close it you will need the Dispose() or Close() method. In the other hand, if you use the Show() method and you close it, the form will be disposed and can not be modified after.
If you are displaying child form as a modal dialog box, you can set DialogResult property of child form with a value from the DialogResult enumeration which in turn hides the modal dialog box, and returns control to the calling form. At this time parent can access child form's data to get the info that it need.
For more info check this link:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult(v=vs.110).aspx
i had same problem i solved it like that , here are newbies step by step instruction
first create object of child form it top of your form class , then use that object for every operation of child form like showing child form and reading value from it.
example
namespace ParentChild
{
// Parent Form Class
public partial class ParentForm : Form
{
// Forms Objects
ChildForm child_obj = new ChildForm();
// Show Child Forrm
private void ShowChildForm_Click(object sender, EventArgs e)
{
child_obj.ShowDialog();
}
// Read Data from Child Form
private void ReadChildFormData_Click(object sender, EventArgs e)
{
int ChildData = child_obj.child_value; // it will have 12345
}
} // parent form class end point
// Child Form Class
public partial class ChildForm : Form
{
public int child_value = 0; // variable where we will store value to be read by parent form
// save something into child_value variable and close child form
private void SaveData_Click(object sender, EventArgs e)
{
child_value = 12345; // save 12345 value to variable
this.Close(); // close child form
}
} // child form class end point
} // name space end point
Many ways to skin the cat here and #Mitch's suggestion is a good way. If you want the client form to have more 'control', you may want to pass the instance of the parent to the child when created and then you can call any public parent method on the child.
I think the easiest way is to use the Tag property
in your FormOptions class set the Tag = value you need to pass
and after the ShowDialog method read it as
myvalue x=(myvalue)formoptions.Tag;
When you use the ShowDialog() or Show() method, and then close the form, the form object does not get completely destroyed (closing != destruction). It will remain alive, only it's in a "closed" state, and you can still do things to it.
The fastest and more flexible way to do that is passing the parent to the children from the constructor as below:
Declare a property in the parent form:
public string MyProperty {get; set;}
Declare a property from the parent in child form:
private ParentForm ParentProperty {get; set;}
Write the child's constructor like this:
public ChildForm(ParentForm parent){
ParentProperty= parent;
}
Change the value of the parent property everywhere in the child form:
ParentProperty.MyProperty = "New value";
It's done. the property MyProperty in the parent form is changed. With this solution, you can change multiple properties from the child form. So delicious, no?!

Is there a way to get last form class from the calling stack?

I have a custom message box (a winform basically) which pops up on the center of the calling form, like this:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
MsgBox.Show(this, "asdsdfsdf");
}
}
Here I pass this (Form1) as the owner of MsgBox. Now I know where to position the MsgBox form since I am passing the parent form (Form1) as well.
But I need this custom messagebox to align itself (center to parent form) even if called from other classes, for eg,
public class Computer
{
public void Do(int i)
{
MsgBox.Show(i.ToString());
}
}
The problem here is I can't pass reference of the parent form to MsgBox class. So here I wont be able to position the custom box. What I would love to have is an ability for MsgBox class to determine which is the last form class in the call stack?
I tried this:
public partial class MsgBox : Form
{
private void X()
{
StackTrace df = new StackTrace();
foreach (var item in df.GetFrames())
{
var type = item.GetMethod().DeclaringType;
if (type.BaseType == typeof(Form))
{
IWin32Window w = //how to get the form instance here??
//------------
break;
}
}
}
}
I do get upto the inner if clause; the problem is that I dont know how to get the form instance or the IWin32Window handle of the form from the type variable.. Is there something I can do to get the instances itself of the classes rather than the types?
A Big Edit: Apologies, that's been a big mistake I made to say that getting the reference of parent form is to center the child form. I need parent form's handle in MsqBox instance as it does other things as well. In short I need the parent form in child form without reference of parent not being passed. Is it possible?
You could try centering your MessageBox on Form.ActiveForm.
The solution:
Keep the private Form Parent { get; private set; } property in each MsgBox class instance.
Create MsgBox.ActiveForm { get { .. } } static property which will pick the Form.ActiveForm and if it is of type MsgBox then return it's parent.
Static property of MsgBox class:
public static Form ActiveForm
{
get
{
return Form.ActiveForm == null ? null :
Form.ActiveForm is MsgBox ? ((MsgBox)Form.ActiveForm).Parent :
Form.ActiveForm;
}
}
This is one way of doing it, thanks #Joe:
public static Form GetLastForm()
{
if (Form.ActiveForm != null && !(Form.ActiveForm is MsgBox))
return Form.ActiveForm;
var openForms = Application.OpenForms.Cast<Form>().Where(f => !(f is MsgBox));
if (openForms.Count > 0)
return openForms[openForms.Count - 1];
return null;
}
I had problem getting the correct parent form thru stack trace approach. Here the basic confusion is to identify if I wanted the current active form, or the last opened form, or the form that caused the MsgBox to pop up. All three can be different, and I went for stack trace approach so as to get third one. Depending on stack trace was frustrating. I just now get the active form, if not I retrieve the last opened form. Application.OpenForms have the forms in exact correct order forms were opened.

accessing controls on parentform from childform

I want to change text in textbox on parentform from childform.
I set textbox
modifiers= public
i have extra written a function in parentform
public TextBox txtbox
{
get
{
return mybox;
}
set
{
mybox= value;
}
}
in child form on writing
this.ParentForm. ( can't see mybox).
what i am missing.
regards,
Since ParentForm will return a Form and not your form, you need to cast it before you can access any of your custom properties:
((MyForm)this.ParentForm).textbox = "new text!";
Additionally, you are setting the whole control, not just the text.
Try this, to expose the text property only:
public string txtbox
{
get
{
return mybox.Text;
}
set
{
mybox.Text = value;
}
}
I think the problem is that ParentForm is of type Form which does not have a member txtbox. You need to cast ParentForm to your form (suppose it is Form1), like:
((Form1)this.ParentForm).txtbox
Random guess without seeing any actual code: mybox is likely not declared public.
Edit: Or, ah, yes, as Andrei says - you havn't cast the ParentForm to your parent form's type.

Categories

Resources