Add Form to a UserControl - is this possible? - c#

Normally, controls are being added to forms. But I need to do an opposite thing - add a Form instance to container user control.
The reason behind this is that I need to embed a third-party application into my own. Converting the form to a user control is not feasible due to complexity.

This is possible by setting the form's TopLevel property to false. Which turns it into a child window, almost indistinguishable from a UserControl. Here's a sample user control with the required code:
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
public void EmbedForm(Form frm) {
frm.TopLevel = false;
frm.FormBorderStyle = FormBorderStyle.None;
frm.Visible = true;
frm.Dock = DockStyle.Fill; // optional
this.Controls.Add(frm);
}
}

Related

Cross form communication

I have a program with two forms.
The second form, Form2 in which I want a few labels initialized with values from the main form.
The code:
public Form2()
{
InitializeComponent();
Form1 mainForm = (Form1)this.Owner;
lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
}
For some reason this does not work in the Form2() section, this.Owner is null. But if I was to place the code in an event method it works just fine.
How can I fix that?
The second form shouldn't need to even know about your main form in the first place. Even if it did, it's an extremely bad idea to be reading into its internal controls.
Instead your second form should have public properties through which it can accept the data that your main form wants to provide to it, without exposing any of its internal controls, and the main form can set those properties using the data from its controls. You could also potentially use parameters to the constructor instead, if you have just a bit of data, and that is the only time you need to provide it.
public class Form2
{
public string Name
{
get { return lblName.Text; }
set { lblName.Text = value; }
}
}
public class MainForm
{
public void Foo()
{
Form2 child = new Form2();
child.Name = mainForm.gvRow.Cells[2].Value.ToString();
child.Show();
}
}
This code is executed when the Form2 form is created. The Owner isn't set yet (and, presumably, the data isn't present yet). If you put it in the VisibleChanged event handler - it will be executed when the Owner and data are (presumably) present.
Use the Load Event. The Owner is only initialized after you Show the form, which then in return raises the Load Event.
Owner isn't set until the form is shown - i.e. in ShowDialog, not during the constructor. You should pass the parent as a parameter in the constructor:
public Form2(Form1 mainForm)
{
InitializeComponent();
lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
}
That's because the Owner is not initialized yet in the Form2 constructor, set your code in your Form2_Load event
Use the Form.Show(IWin32Window) overload to pass the owner to the child form.
http://msdn.microsoft.com/en-us/library/szcefbbd(v=vs.110).aspx
You need to set the Owner property yourself
As an alternative you could pass a reference to Form1 to the Form2 constructor. In the code that opens Form2 you probably have something like this:
var form2 = new Form2();
form2.Show();
You could replace that with:
var form2 = new Form2(this);
form2.Show();
In Form2 you'd add a constructor overload:
public Form2(Form1 owningForm)
{
InitializeComponent();
Form1 mainForm = owningForm;
lblName.Text = mainForm.gvRow.Cells[2].Value.ToString();
lblItemType.Text = mainForm.gvRow.Cells[1].Value.ToString();
lblLocation.Text = mainForm.gvRow.Cells[3].Value.ToString();
}
If different "owning forms" are possible you may need to define an interface instead of passing Form2.

Visible Property of Picture box not working from another form in C#

Hi I am using windows forms in C#. I am trying to modify the visible property of a picture from main form to another. Initially, the visible property of the picture box is set to false. On a button click from another form, the visible property of the picture box is modified to true.
This is the code written in the Form2 method:
private void button_Click(object sender, EventArgs e)
{
public Form1 frm1 = new Form1();
frm1.pictureBox.Visible= true;
}
Form1 is an instance type, so when you do
public Form1 frm1 = new Form1();
frm1.pictureBox.Visible= true;
you're really just creating a new instance of Form1 completely unrelated from your original Form1, changing a picture-box's visible property on it, and then discarding it.
What you can do, is put a reference to the "parent" Form1 inside your Form2 class.
Here's an example
public partial class Form2 : Form
{
public Form2(Form1 parent)
{
InitializeComponent();
this.Parent = parent;
}
Form1 Parent;
private void button1_Click(object sender, EventArgs e)
{
Parent.pictureBox.Visible= true;
}
...
}
there you create an instance of a form :
public Form1 frm1 = new Form1();
This is then obviously NOT the form you already may have in your page, which you could simply access by its ID.
According to your written code it will create new instance of the desired form, and NOT take the existing open form. Hence to identify the existing open form containing target picture box you need the target form and controlling form be related by like Parent form or MDI Parent Form.
Assuming case of MDI Parent Form (i.e. Controlling form is MDI Parent of Target Form), you need following codes to identify to existing open form:
foreach (Form frm in MdiChildren)
{
if (frm is myTargetForm)
{
//do your code to find control using id of picture box and change the required properties
}
}

Change TopMost property on a DIFFERENT form?

So in my program I have a settings page. On the settings page, there is an option to set the program "Always on Top". When this option is checked and unchecked, it properly saves the setting, but it does not actually change TopMost property itself.
The program's main form is called "MainForm", but the settings page is called "SettingsForm". How would I change the "TopMost" property on "MainForm", from within the "SettingsForm"?
You could create an event on Settings form:
public event EventHandler TopMostEvent;
private void OnTopMostEvent()
{
if (TopMostEvent != null)
{
TopMostEvent(this, EventArgs.Empty);
}
}
On CheckedChanged event call the method after saving settings:
OnTopMostEvent();
And in Main form subscribe to the event and set the forms TopMost property
One approach would be to simply give SettingForm a reference to MainForm, e.g. via a constructor parameter which is then stored to a field where it can later be accessed when necessary.
For example:
public class SettingsForm
{
public SettingsForm(MainForm mainForm)
{
this.mainForm = mainForm;
}
public void Apple()
{
this.mainForm.TopMost = true;
}
private readonly MainForm mainForm;
}
public class MainForm
{
public void Banana()
{
var settingsForm = new SettingsForm(this);
settingsForm.ShowDialog();
}
}
(However, it may not be necessary to do this if the owner of SettingsForm is already the insntance of MainForm but this I cannot tell from what you have given.)
This is a good place for a mediator pattern. (Similar to a controller) The idea is you have one object that creates all of your windows and passes a reference to itself into each form through the constructor. You can call a method in the mediator from either form and the mediator will focus the MainForm. It's a very common practice in Windows Forms.
So you'll make a mediator class like so:
public class MyMediator
{
Form mainForm {get;set;}
Form settingsForm{get;set;}
public MyMediator()
{
mainForm = new MainForm(this);
mainForm.Show();
}
...
public FocusMainForm() // call this from settings form
{
mainForm.TopMost = true;
}
}

How can I use a custom control class that inherits from a built-in control on my main form?

I have a mydatagridview class which inherits from the built-in DataGridView control, as shown below:
public class mydatagridview : DataGridView
{
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
this.ProcessTabKey(e.KeyData);
return true;
}
return base.ProcessDataGridViewKey(e);
}
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
this.ProcessTabKey(keyData);
return true;
}
return base.ProcessDialogKey(keyData);
}
}
Now I want to utilize it in my main class:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
I want to Utilize myDatagridview with Datagridview1 of : public partial class Form1 : Form
How can I do this?
You need to create an instance of your custom control class, and then add that instance to your form's Controls collection. For example:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Create an instance of your custom control
mydatagridview myDGV = new mydatagridview();
// Add that instance to your form's Controls collection
this.Controls.Add(myDGV);
}
}
Of course, you could also do the same thing from the Designer. It will automatically insert code very similar to that shown above inside the InitializeComponent() method.
If your custom control doesn't show up in the Toolbox automatically after you've rebuilt your project, make sure that you've enabled toolbox auto-population:
From the "Tools" menu, select "Options".
Expand the "Windows Forms Designer" category.
Set the "AutoToolboxPopulate" property to True.
If I understand correctly, and i'm not sure that I do, you can just use it like any other type:
mydatagridview mydatagrid = new mydatagridview();
this.Controls.Add(mydatagrid);
Next to the answers that have already been given, it should be possible to drag and the drop the control from the toolbox to your form.
If you create a user control, or a custom Control, and build your project, the control should show up in the toolbox.

C# WinForms MDI problem

Hello guyes i have one problem i have 1 parent form and 3 children i just want to open them maximized but when i do that in left side comes this 3 controls. How can i open one form without this controls.
If im doing this with wrong way please advice me something does mdi good for such things?
please see this pictures http://img440.imageshack.us/img440/6831/mdinz.jpg
http://img139.imageshack.us/img139/4687/mdi1.jpg
This is a known bug in the MDI implementation, triggered when you create a maximized child window in the parent constructor. This is an example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
var child = new Form2();
child.MdiParent = this;
child.WindowState = FormWindowState.Maximized;
child.Show();
}
}
You'll see the min/max/restore glyphs displayed twice, restoring the child window leaves the MDI bar on the screen, just as in your first screen shot. The workaround is to move the child creation code to the OnLoad() method. Like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
var child = new Form2();
child.MdiParent = this;
child.WindowState = FormWindowState.Maximized;
child.Show();
}
}
You can use the ControlBox, FormBorderStyle, MaximizeBox and MinimizeBox properties to remove the various window UI elements from a form, if you wish.

Categories