I have a form. I want to make sure that the RegisterForm.cs form comes as childform when the toggle button I added on this form is activated. It works in a different position from the main panel when I call it normally. Whatever I've done, I haven't been able to solve this problem, can you help me with that?
FormMainMenu.cs
public void OpenChildForm(Form childForm)
{
if (currentChildForm != null)
{
//open only form
currentChildForm.Close();
}
currentChildForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelDesktop.Controls.Add(childForm);
panelDesktop.Tag = childForm;
childForm.BringToFront();
childForm.Show();
lblTitleChildForm.Text = childForm.Text;
}
SozlesmeFormu.cs
public partial class SozlesmeFormu : Form
{
private bool toggleCheck = false;
public SozlesmeFormu()
{
InitializeComponent();
textBox1.Multiline = true;
textBox1.ScrollBars = ScrollBars.Both;
}
private void toggleSozlesme_CheckedChanged(object sender, EventArgs e)
{
toggleCheck = true;
toggleSozlesme.Enabled = false;
toggleSozlesme.OnBackColor = Color.DarkGray;
this.Close();
FormMainMenu formMain = new FormMainMenu();
formMain.OpenChildForm(new RegisterForm());
}
}
Whatever I did, I couldn't call RegisterForm as childform. It's always irrelevant from the main panel.
Related
This question already has answers here:
"Invoke or BeginInvoke cannot be called on a control until the window handle has been created" only occurs the second time form opens
(1 answer)
Invoke or BeginInvoke cannot be called on a control until the window handler has been created
(1 answer)
Closed 1 year ago.
I have Windows Form project that turns one format of csv file into another.
I am trying to show the converting progress while converting.
Converting method throws an exception if converting fails.
When converting fails, I close ConvertingScreen but when I close ConvertingScreen System.InvalidOperationException occurs.
invoke or begininvoke cannot be called on a control until the window handle has been created
It seems it never happens if I add some waits before I close. I have tried checking HandleCreated but it didnt go well. I used to do this kind of jobs by adding only visible label while it is on progress. This is my first time doing such like this way. Is this bad practice? If not how can I fix this? Below is simple code that can describe everything what is happening to me.
// MainForm
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
ConvertingScreen.ShowScreen();
// Converts here and results in failure so throwing an exception
throw new NotImplementedException();
}
catch (Exception)
{
ConvertingScreen.CloseForm();
MessageBox.Show("error");
}
}
}
// ConvertingScreen
public class ConvertingScreen : Form
{
public ConvertingScreen()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
// label1
this.label1.Font = new System.Drawing.Font("MS UI Gothic", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(316, 22);
this.label1.TabIndex = 0;
this.label1.Text = "";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
// ConvertingScreen
this.BackColor = System.Drawing.Color.LightGray;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.ClientSize = new System.Drawing.Size(340, 40);
this.ControlBox = false;
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(340, 40);
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(340, 40);
this.Name = "ConvertingScreen";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "ConvertingScreen";
this.TopMost = true;
this.ResumeLayout(false);
}
private Label label1;
private delegate void CloseDelegate();
private delegate void UpdateTextDelegate(string text);
private static ConvertingScreen form;
public static void ShowScreen()
{
if (form != null) return;
form = new ConvertingScreen();
Thread thread = new Thread(new ThreadStart(ConvertingScreen.ShowForm));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
private static void ShowForm()
{
if (form != null) Application.Run(form);
}
public static void CloseForm()
{
form?.Invoke(new CloseDelegate(ConvertingScreen.CloseFormInternal));
}
private static void CloseFormInternal()
{
if (form != null)
{
form.Close();
form = null;
}
}
public static void Update(string text)
{
if (form != null) form.UpdateLabel(text);
}
private void UpdateLabel(string text)
{
if (InvokeRequired)
{
this.Invoke(new UpdateTextDelegate(UpdateLabel), new object[] { text });
return;
}
label1.Text = text;
}
}
Im wondering how I would reveal a label, and a textbox once a checkbox has been checked.
I know in my project, everything below initialize component starts once the form is visible, so i try this.
public Form2()
{
InitializeComponent();
if (checkBox1.Checked == true)
{
label9.Visible = true;
textBox4.Visible = true;
}
else
{
label9.Visible = false;
textBox4.Visible = false;
}
}
but that doesnt work, and so i put it in a while(true) loop, which is just an infinite loop
public Form2()
{
while (true)
{
InitializeComponent();
if (checkBox1.Checked == true)
{
label9.Visible = true;
textBox4.Visible = true;
}
else
{
label9.Visible = false;
textBox4.Visible = false;
}
}
}
but that doesnt work either, if someone knows the answer, please let me know :).
You just need to use the checked changed event of the checkbox.
And call it from the constructor to initialize the state of the controls.
Also you only need to assign the Checked property to the Visible properties.
public Form2()
{
InitializeComponent();
checkBox1_CheckedChanged(checkBox1, EventArgs.Empty);
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
label9.Visible = checkBox1.Checked;
textBox4.Visible = checkBox1.Checked;
}
Or you can use the form load to leave the constructor as is:
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1_CheckedChanged(checkBox1, EventArgs.Empty);
}
Order of Events in Windows Forms
Control.Created Property
But never put an infinite loop in the constructor or in form load or shown!
And never put such infinite loop without break somewhere...
That will freeze the application in it.
I'm designing a Windows Form to create a child form at run time. I would like that the child form build controls (buttons, list boxes, etc.) depending on a the text entered in the parent form. My problem is when I close the child form, enter new text and relaunch the child form, the same control is being created.
This is how I call the child form:
private void button2_Click(object sender, EventArgs e)
{
try
{
Form2 frm2 = new Form2();
frm2.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This is the code in the child form
try
{
this.MaximizeBox = false;
this.MinimizeBox = false;
this.BackColor = Color.White;
this.ForeColor = Color.Black;
this.Size = new System.Drawing.Size(550, 550);
this.Text = "Test Create form in run time ";
Form1 frm1 = new Form1();
if (frm1.master == "button")
{
this.btnAdd.BackColor = Color.Gray;
this.btnAdd.Text = "Add";
this.btnAdd.Location = new System.Drawing.Point(90, 25);
this.btnAdd.Size = new System.Drawing.Size(50, 25);
this.Controls.Add(btn);
}
}
Can anyone give me a piece of code or link ?
The problem is that you are not sending the text from From1, instead you are creating a new Form1 inside Form2. This is not what you want I guess...
To solve this:
Add a String property in Form2, called say 'ControlText'.
Suppose that the user write the text in a text box called Text1 in
Form1
Then you would call form2 from Form1 like this:
private void button2_Click(object sender, EventArgs e)
{
try
{
Form2 frm2 = new Form2();
frm2.ControlText = Text1.text
frm2.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Finally, the code in form2 will be something like this:
try
{
this.MaximizeBox = false;
this.MinimizeBox = false;
this.BackColor = Color.White;
this.ForeColor = Color.Black;
this.Size = new System.Drawing.Size(550, 550);
this.Text = "Test Create form in run time ";
if (ControlText == "button")
{
this.btnAdd.BackColor = Color.Gray;
this.btnAdd.Text = "Add";
this.btnAdd.Location = new System.Drawing.Point(90, 25);
this.btnAdd.Size = new System.Drawing.Size(50, 25);
this.Controls.Add(btn);
}
}
hope this may help you
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Utilities.ResetAllControls(this);
}
public class Utilities
{
public static void ResetAllControls(Control form)
{
foreach (Control control in form.Controls)
{
if (control is TextBox)
{
TextBox textBox = (TextBox)control;
textBox.Text = null;
}
if (control is ComboBox)
{
ComboBox comboBox = (ComboBox)control;
if (comboBox.Items.Count > 0)
comboBox.SelectedIndex = 0;
}
if (control is CheckBox)
{
CheckBox checkBox = (CheckBox)control;
checkBox.Checked = false;
}
if (control is ListBox)
{
ListBox listBox = (ListBox)control;
listBox.ClearSelected();
}
}
}
}
Try this
foreach(control in this.Controls)
{
this.Controls.Remove(control);
control.Dispose();
}
this.Controls.Clear();
I have Form1 with 2 radio buttons (rb1 and rb2) and one ordinary button (btn). When I click on btn I should open Form2, as MDI child of Form1 if rb1 is checked, or as ordinary Dialog if rb2 is checked. Also, there can only be one Form2 opened at any moment.
This is my code:
public partial class Form1 : Form
{
Form2 f2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null)
{
MessageBox.Show("Close form!");
return;
}
f2 = new Form2();
if (radioButton1.Checked == true)
{
this.IsMdiContainer = true;
f2.MdiParent = this;
f2.Show();
}
else
{
f2.Show();
}
f2.FormClosed += f2_FormClosed;
}
void f2_FormClosed(object sender, FormClosedEventArgs e)
{
this.IsMdiContainer = false;
f2 = null;
}
}
Everything works as it should except when I maximize Form2 as MDI child and then close it. After that screen stays the same (as I even didn't closed Form2) but I am able to open new Form2, and then Form1's title is "Form1 - [Form2]", and if I repeat the process it would be "Form1 - [Form2] - [Form2]", etc.
I figured out that I my f2_FormClosed method should be
void f2_FormClosed(object sender, FormClosedEventArgs e)
{
f2.Hide(); // <<<<<<<<-----------NEW
this.IsMdiContainer = false;
f2 = null;
}
but I don't know why; Form2 should be closed, I don't know why should I have to hide it?!
Thanks!
I agree with Hans, switching IsMdiContainer at run-time is wonky and is likely to produce other side-effects you haven't seen yet.
Seriously consider a different design for your app.
With that in mind, here's probably the stupidest hack I'll post all day:
public partial class Form1 : Form
{
Form2 f2;
System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
tmr.Interval = 100;
tmr.Enabled = false;
tmr.Tick += delegate (object sender, EventArgs e) {
tmr.Stop();
this.IsMdiContainer = false;
};
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null)
{
MessageBox.Show("Close form!");
return;
}
f2 = new Form2();
f2.FormClosed += delegate(object sender2, FormClosedEventArgs e2) {
f2 = null;
};
if (radioButton1.Checked == true)
{
this.IsMdiContainer = true;
f2.FormClosed += delegate(object sender3, FormClosedEventArgs e3) {
tmr.Start();
};
f2.MdiParent = this;
}
f2.Show();
}
}
*I originally tried Invoking the call to change IsMdiContainer but that didn't work, so I switched to the Timer. Stupidity that works. Use this solution with caution...
my request is suppose i have two sdi form. one sdi main form has button and when user click on that button then a overlay semi transparent window will appear and cover the main sdi form and as well as another sdi will come on top of the over lay window.
here is my overlay window code
namespace CSRAssistant
{
public partial class MaskedDialog : Form
{
static MaskedDialog mask;
static Form frmContainer;
private Form dialog;
private UserControl ucDialog;
private MaskedDialog(Form parent, Form dialog)
{
this.dialog = dialog;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private MaskedDialog(Form parent, UserControl ucDialog)
{
this.ucDialog = ucDialog;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Black;
this.Opacity = 0.50;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}
private void AdjustPosition(object sender, EventArgs e)
{
Form parent = sender as Form;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
this.ClientSize = parent.ClientSize;
}
//
public static DialogResult ShowDialog(Form parent, Form dialog)
{
mask = new MaskedDialog(parent, dialog);
dialog.StartPosition = FormStartPosition.CenterParent;
mask.MdiParent = parent.MdiParent;
mask.Show();
DialogResult result = dialog.ShowDialog(mask);
mask.Close();
return result;
}
public static DialogResult ShowDialog(Form parent, UserControl dialog)
{
mask = new MaskedDialog(parent, dialog);
frmContainer = new Form();
frmContainer.ShowInTaskbar = false;
frmContainer.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmContainer.StartPosition = FormStartPosition.CenterParent;
frmContainer.Height = dialog.Height;
frmContainer.Width = dialog.Width;
frmContainer.Controls.Add(dialog);
mask.MdiParent = parent.MdiParent;
mask.Show();
DialogResult result = frmContainer.ShowDialog(mask);
frmContainer.Close();
mask.Close();
return result;
}
public static void CloseDialog()
{
if (frmContainer != null)
{
frmContainer.Close();
}
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// MaskedDialog
//
this.ClientSize = new System.Drawing.Size(284, 262);
this.Name = "MaskedDialog";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MaskedDialog_FormClosing);
this.Load += new System.EventHandler(this.MaskedDialog_Load);
this.ResumeLayout(false);
}
private void MaskedDialog_Load(object sender, EventArgs e)
{
}
private void MaskedDialog_FormClosing(object sender, FormClosingEventArgs e)
{
}
}
}
this way i am calling my overlay when user click on main sdi button.
Form2 f2 = new Form2();
f2.Show();
MaskedDialog.ShowDialog(this, f2);
f2.Dispose();
f2 = null;
when i am running the code and MaskedDialog.ShowDialog(this, f2); is calling then i am getting a error....the error message is Form that is already visible cannot be displayed as a modal dialog box. Set the form's visible property to false before calling showDialog.
so i am not being able to understand where i am making the mistake. anyone can help me to fix the problem. thanks
You're doing this wrong - call mask.ShowDialog(), not mask.Show() and dialog.ShowDialog(). The error message is pretty clear - you can't ShowDialog a form that's already visible - and that's exactly what you're doing in dialog.ShowDialog(mask);.
Or, in a way that probably more closely shows what you want to do, when calling MaskedDialog.ShowDialog, do this:
Form2 f2 = new Form2();
MaskedDialog.ShowDialog(this, f2);
In other words - don't show the form you're going to ShowDialog. It's going to be made visible by the ShowDialog call.