Close childForm when Open a New childForm in MDI Parent? - c#

I have a treeView to open each child Form, but when I open new child form I can still see the previous child form behind the new child form. What I want to do is close the old child form when open a new one. (childForm.Close(); // not working somehow)
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
string selectedNodeText = e.Node.Text;
Form1 myform1 = new Form1();
Form2 myform2 = new Form2();
if (selectedNodeText == "1")
{
myform1.MdiParent = this;
myform1.Parent = this.splitContainer1.Panel2;
myform1.Dock = DockStyle.Fill;
this.splitContainer1.Panel2.Controls.Add(myform1);
myform1.BringToFront();
myform1.Show();
}
if (selectedNodeText == "2")
{
myform2.MdiParent = this;
myform2.Parent = this.splitContainer1.Panel2;
myform2.Dock = DockStyle.Fill;
this.splitContainer1.Panel2.Controls.Add(myform2);
myform2.BringToFront();
myform2.Show();
}
}

Take a look at the MdiChildren property of your form object. There is a reference to all forms you attached to your MdiContainer.
Another way is to store the reference to your forms in the class itself and close the old one if you open another:
private Form1 myform1 = null;
private Form2 myform2 = null;
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) {
string selectedNodeText = e.Node.Text;
if (selectedNodeText == "1" && myform1 == null) {
myform1 = new Form1()
// ... some code ...
if (myform2 != null) {
myform2.Close();
myform2 = null;
}
}
if (selectedNodeText == "2" && myform2 == null) {
myform2 = new Form2()
// ... some code ...
if (myform1 != null) {
myform1.Close();
myform1 = null;
}
}
}

Related

I open 5 different forms via Form1 but i can't save all positions

I have a project and I'm locked. I open different forms on Form1 you see below in the code. I did this with "notifyIcon". Instead of opening 5 different forms, I am bringing one by changing the form. I have 5 forms on my screen. But my problem is; I can save the locations of the forms. Technically they all come from the same form, so they all start from the same position. Do you have a recommendation?
Edit :
A new idea came to mind. but I need your help again. when I close the form, I can save the form's position to a TxT file and manually start the positions with the positions from TxT when the forms are opened.
private void Form1_Load(object sender, EventArgs e)
{
this.Hide();
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
}
private void tCKToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string tckRenk = satirlar[0];
Color tckColor = System.Drawing.ColorTranslator.FromHtml(tckRenk);
Form2 tckForm = new Form2();
tckForm.Opacity = .50;
tckForm.TopMost = true;
tckForm.BackColor = tckColor;
tckForm.LabelText = "TCK";
tckForm.Show();
}
private void aDAToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string adaRenk = satirlar[1];
Color adaColor = System.Drawing.ColorTranslator.FromHtml(adaRenk);
Form2 adaForm = new Form2();
adaForm.Opacity = .50;
adaForm.TopMost = true;
adaForm.BackColor = adaColor;
adaForm.LabelText = "ADA";
adaForm.Show();
}
You can set From Location
Form frm2 = new Form();
frm2.StartPosition = FormStartPosition.Manual;
frm2.Left = 500;
frm2.Top = 500;
frm2.Show();
public static class extensions
{
public static void SaveFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.CreateSubKey(form.Name))
{
if (key != null)
{
if (form.WindowState == FormWindowState.Normal)
{
key.SetValue("Left", form.Left);
key.SetValue("Top", form.Top);
key.SetValue("Width", form.Width);
key.SetValue("Height", form.Height);
}
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
key.SetValue("WindowState", form.WindowState);
}
}
}
}
catch
{
// Party on, Garth!
}
}
public static void LoadFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.OpenSubKey(form.Name))
{
if (key != null)
{
form.Left = (int)key.GetValue("Left", form.Left);
form.Top = (int)key.GetValue("Top", form.Top);
form.Width = (int)key.GetValue("Width", form.Width);
form.Height = (int)key.GetValue("Height", form.Height);
// Move window into visible screen bounds if outside screen bounds (prevent off-screen hidden windows)
Rectangle screenRect = SystemInformation.VirtualScreen;
if (form.Left < screenRect.Left)
form.Left = screenRect.Left;
if (form.Top < screenRect.Top)
form.Top = screenRect.Top;
if (form.Right > screenRect.Right)
form.Left = screenRect.Right - form.Width;
if (form.Bottom > screenRect.Bottom)
form.Top = screenRect.Bottom - form.Height;
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
windowState = key.GetValue("WindowState", windowState).ToString();
form.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), windowState);
}
}
}
}
catch
{
// Party on, Wayne!
}
}
}
Use this extension methods and call it on form shown, form Closing & form Move events
For Complete Working Sample
public partial class Form3 : Form
{
private int count = 1;
public Form3()
{
InitializeComponent();
}
private void Form2_Move(object sender, EventArgs e)
{
this.SaveFormSizeAndLocation();
}
protected override void OnShown(EventArgs e)
{
Text = Name;
base.OnShown(e);
this.LoadFormSizeAndLocation();
this.Move += Form2_Move;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
this.SaveFormSizeAndLocation();
}
private void button1_Click(object sender, EventArgs e)
{
var frm = new Form3();
frm.Name = "inner" + count.ToString();
frm.Show();
count++;
}
}

Avoid duplicate form loading in c#

I have 2 windows forms.Both Form1 and form2 have a button. When I click the button in form1 it shows form2 and vice versa. But it create a duplicate form when I click button on each time. How to avoid it. please tell me. My code is given below.
Form1:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
}
Form2:
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.Show();
}
just use this method common and pass parameter like 'this' when button click
public bool formIsExist(Form frmOpen)
{
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc)
{
if (frm.Name == frmOpen.Name)
{
return true;
}
}
return false;
}
The problem is that you are creating a new form each time you click the button.
To solve this problem You could make your form static.
static Form1 form = new Form1();
private void button1_Click(object sender, EventArgs e)
{
form.Show();
}
My solution, you can try
Form1
private void button1_Click(object sender, EventArgs e)
{
FormCollection fc = Application.OpenForms;
bool present = false;
foreach (Form frm in fc)
{
if (frm.Name == "Form2")
{
present = true;
}
}
if (!present)
{
Form2 f2 = new Form2();
f2.Show();
}
}
Form2
private void button1_Click(object sender, EventArgs e)
{
FormCollection fc = Application.OpenForms;
bool present = false;
foreach (Form frm in fc)
{
if (frm.Name == "Form1")
{
present = true;
}
}
if (!present)
{
Form1 f1 = new Form1();
f1.Show();
}
}
The easiest way is to determine whether the target form is already there and in that case, open it.
For example, in Form1 do this:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = null;
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i] is Form2)
{
f2 = Application.OpenForms[i];
break;
}
}
if (f2 == null)
f2 = new Form2();
f2.Show();
}
To make a common method for all forms, you could try this:
public static T GetForm<T>() where T : Form
{
for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i] is T)
return (T)Application.OpenForms[i];
}
return null;
}
And call it like:
Form2 f2 = GetForm<Form2>();
if (f2 == null) f2 = new Form2();
#Mostafiz' answer is almost correct. It just misses the code to show the found present form. (Sorry, do not yet have 50 reputation to write this as a comment)
Try this code:
Form1:
private void button1_Click(object sender, EventArgs e)
{
Form form = null;
//search all opened forms for one with name "Form2"
foreach( Form frm in Application.OpenForms )
if( frm.Name == "Form2" ) //this requires Form2 to be named "Form2"
{
form = frm;
break;
}
//if no opened Form2 was found, create a new one
if( form == null )
form = new Form2();
form.Show();
}
Form2:
private void button1_Click(object sender, EventArgs e)
{
Form form = null;
//search all opened forms for one with name "Form1"
foreach( Form frm in Application.OpenForms )
if( frm.Name == "Form1" ) //this requires Form1 to be named "Form1"
{
form = frm;
break;
}
//if no opened Form1 was found, create a new one
if( form == null )
form = new Form1();
form.Show();
}

How to check if Window is already open? Duplicate Windows

I have a button that opens a Window.
If the button is pressed again, it opens a duplicate of the same window.
info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
How do you check if the Window is already open, and deny a duplicate from being opened again?
I can't use info.ShowDialog() because it disables the Main Window.
Solutions that have not worked:
Info info = new Info();
if (!info.IsActive)
{
info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
}
Info info = new Info();
if (info.Visibility != Visibility.Visible)
{
info.Owner = Window.GetWindow(this);
info.Show();
}
public static bool IsWindowOpen<T>(string name = "") where T : Window
{
return string.IsNullOrEmpty(name)
? Application.Current.Windows.OfType<T>().Any()
: Application.Current.Windows.OfType<T>().Any(w => w.Name.Equals(name));
}
private void buttonInfo_Click(object sender, RoutedEventArgs e)
{
if (!IsWindowOpen<Window>("Info"))
{
Info info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
}
}
Create a form only when value is not null.
If the form was closed put the value back to null with the FormClosed event.
public static Info info;
if(info == null){
info = new Info();
info.Show();
}
put an event form close on the info form
private void info_FormClosed(object sender, FormClosedEventArgs e)
{
MainForm1.info = null;
}
It works for me
The sensible approach is to just keep track of the Window instance so you don't have to find it back later. Add a field:
private Info infoWindow;
If it is null then you know that the window doesn't exist yet, so you'll want to create it. Use the Closed event to set the variable back to null. If it is not null then you want to make sure that the window gets restored. So:
private void button_Click(object sender, RoutedEventArgs e) {
if (infoWindow == null) {
infoWindow = new Info();
infoWindow.Closed += (s, ea) => infoWindow = null;
infoWindow.Owner = this; // optional
infoWindow.Show();
}
else {
if (infoWindow.WindowState == WindowState.Minimized) {
infoWindow.WindowState = WindowState.Normal;
}
infoWindow.Activate();
}
}
And you probably also want to close the window automatically when the window that contains the button is closed:
private void Window_Closed(object sender, EventArgs e) {
if (infoWindow != null) infoWindow.Close();
}
You could use .IsLoaded field or bind the .ContentRendered event
Edit 1 -
Window1:
public class Window1 : Window
{
private Info info = null;
private Boolean IsInfoOpened = false;
protected void OpenInfo()
{
if (this.IsInfoOpened) return;
this.info = new Info();
this.info.ContentRendered += delegate { this.IsInfoOpened = true; };
this.info.Closed += delegate { this.IsInfoOpened = false; }
this.info.Show();
}
}

form.Show in function not working when called

public static object loadForm(Form formToLoad, TabControl homeTabControl)
{
//Check if formToLoad parameter is NULL
if (formToLoad == null) throw new ArgumentNullException("formToLoad");
//get the parent/ownining form
Form form1 = new Form1();
//set formToLoad properties
formToLoad = new Form
{
Owner = form1,
FormBorderStyle = FormBorderStyle.None,
TopLevel = false,
Dock = DockStyle.Fill
};
//add formToLoad to tabControl tabPage
homeTabControl.TabPages["tabPageHome"].Controls.Add(formToLoad);
formToLoad.Show();
return formToLoad;
}
How come formToLoad does not show in the tabControl Page when i call my code from a button click?
private void button3_Click(object sender, EventArgs e)
{
LeaveMainForm lM = new LeaveMainForm();
AppCode.FormLoader.loadForm(lM, homeTabControl);
}
You are over-writing the actual form you are trying to load with a new Form instance, in this line :
formToLoad = new Form
Try this :
//set formToLoad properties
formToLoad.Owner = form1;
formToLoad.FormBorderStyle = FormBorderStyle.None;
formToLoad.TopLevel = false;
formToLoad.Dock = DockStyle.Fill;

Single instance of all WinForm forms

I am developing a C# Windows Forms application. I would like to have a single instance of all the forms.
So, when the user clicks on the Contact button, for instance, twice, instead of having two contact forms, I would to bring the single instance contact form to the front.
How can I achieve this?
Check if the form exists in collection of open forms before creating and showing the form using Application.OpenForms
if (System.Windows.Forms.Application.OpenForms["Form1"] as Form1 != null)
MessageBox.Show("Form1 is opened");
else
MessageBox.Show("Form1 is not opened");
public static Form GetOpenedForm<T>() where T: Form {
foreach (Form openForm in Application.OpenForms) {
if (openForm.GetType() == typeof(T)) {
return openForm;
}
}
return null;
}
And in your code, where you create the ContactForm:
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
form.Select();
}
Simple as that:
Form fc = Application.OpenForms["Form1"];
if (fc != null)
{
fc.Focus();
}
else
{
Form1 f1 = new Form1();
f1.Show();
}
You can disable the contactButton when it is clicked and open the contactForm-
private void contactButton_Click(object sender, EventArgs e)
{
contactButton.Enabled=false;
//code to open the contactForm
}
When the contactForm is closed, you can re-enable the button-
contactButton.Enabled=true;
Try this combo
First make contact form a global object
private ContactForm contactForm;
Then your contact button handler:
private void contactButton_Click(object sender, EventArgs e)
{
if (contactForm == null)
{
contactForm = new ContactForm();
contactForm.FormClosing += new FormClosingEventHandler(contactForm_FormClosing);
}
contactForm.Show();
}
Then handle the FormClosing event of the ContactForm to hide it rather than close it:
private void contactForm_FormClosing(object sender, FormClosingEventArgs e)
{
contactForm.Hide();
e.Cancel = true;
}
Or if you want the contact form to close, and open as new next time, handle the FormClosed instead:
private void contactForm_FormClosed(object sender, FormClosedEventArgs e)
{
contactForm = null;
}
Then next time the button is clicked, the null if clause will be caught and the form will be set to a new instance and opened.
Form2 form2 = null;
private void button1_Click(object sender, EventArgs e)
{
bool isFormExists = false;
foreach (Form openForm in Application.OpenForms)
{
if (openForm == form2 && openForm!=null)
{
openForm.Focus();
isFormExists = true;
break;
}
}
if (!isFormExists)
{
form2 = new Form2();
form2.Show();
}
}
I'd go with Otiel's answer. Also you can add a WindowState, because if the form is minimized it won't be shown. this answer can be used to get the restore method.
ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
form = new ContactForm();
form.Show();
} else {
//use this (if you want it to be restored to normal and focused)
//no need of extension method
//form.WindowState = FormWindowState.Normal;
//form.Select();
//or use this if you want it to be restored as previous state and focused
//You need a Restore extension method that can be found in the link above
form.Focus();
form.Restore();
}

Categories

Resources