If second form is open, bring to front - c#

I have a button on Form1 that opens Form2(Leaderboard) if Form2 is not open. What I am trying to do is: On Button click, if Form2 is closed, open Form2. Else Form2 is open, bring Form2 to front.
With the below code, clicking the button when leaderboardOpen == true; does nothing at all.
public static bool leaderboardOpen = false;
private void leaderButton_Click(object sender, EventArgs e)
{
if (leaderboardOpen == false)
{
Leaderboard leaderboard = new Leaderboard();
leaderboard.Show();
leaderboardOpen = true;
}
else
{
Leaderboard leaderboard = new Leaderboard();
//Tried the below
//leaderboard.Focus();
//leaderboard.BringToFront();
//leaderboard.TopMost = true;
//leaderboard.Activate();
}
}

Instead of a bool, keep a reference to your instance of Leaderboard itself:
private Leaderboard leader = null;
private void leaderButton_Click(object sender, EventArgs e)
{
if (leader == null || leader.IsDisposed)
{
leader = new Leaderboard();
leader.FormClosed += (s2, e2) => { leader = null; };
leader.Show();
}
else
{
if (leader.WindowState == FormWindowState.Minimized)
{
leader.WindowState = FormWindowState.Normal;
}
leader.BringToFront();
}
}

Got it working with the below code.
private void leaderButton_Click(object sender, EventArgs e)
{
var form = Application.OpenForms.OfType<Leaderboard>().FirstOrDefault();
if (form != null)
{
form.Activate();
}
else
{
new Leaderboard().Show();
}
}

Here is a working code for me
public static bool leaderboardOpen = false;
public static Leaderboard? leaderboardForm = null;
private void leaderButton_Click(object sender, EventArgs e)
{
if (!leaderboardOpened || leaderboardForm is null)
{
// Initialize Leaderboard form if it doesn't exist
leaderboardForm = new Leaderboard();
leaderboardForm.Show();
leaderboardOpened = true;
}
else
{
// Focus on the form
leaderboardForm.Focus();
}
}
Make sure to make leaderboardOpened = false; if the Leaderboard form is closed.

Related

Can't hide labels and text boxes when button is checked

When salaried button is checked, change label "Hour Pay: " to "Salary" and hide the labels and text boxes below it. When Hourly button is checked, return everything to its initial form.
My main issue is when i execute code it does not hide labels and text boxes.
private void addButton_Click(object sender, EventArgs e)
{
}
private void icontype_CheckedChanged(object sender, EventArgs e)
{
if (salariedRadioButton.Checked == true)
{
hourLabel.Visible = false;
}
else if (hourlyRadioButton.Checked == true)
{
hourLabel.Visible = true;
}
}
private void hourTextBox_TextChanged(object sender, EventArgs e)
{
try
{
weekTextBox.Text =(float.Parse(hourTextBox.Text)40).ToString();
}
catch
{
}
try
{
yearTextBox.Text = (float.Parse(weekTextBox.Text) 52).ToString();
}
catch
{
}
}
I'm not sure what's your expected result, for the hide part, I think you can try this, thanks.
public Form1()
{
InitializeComponent();
this.salariedRadioButton.CheckedChanged += icontype_CheckedChanged;
this.hourlyRadioButton.CheckedChanged += icontype_CheckedChanged;
}
private void icontype_CheckedChanged(object sender, EventArgs e)
{
if (salariedRadioButton.Checked == true)
{
hourLabel.Visible = false;
weekTextBox.Visible = false;
}
else if(hourlyRadioButton.Checked == true)
{
hourLabel.Visible = true;
weekTextBox.Visible = true;
}
}

How can I pass 2 variables from one form to another?

I have 2 forms: Game and newPlayer. When you press a button in Game, it opens the dialog of the newPlayer form, where someone would type his/her name and choose a Color in a comboBox between red, green, blue or yellow. I save that information in 2 variables: name (string) and color (int - being the index of the comboBox). I want to pass those 2 variables to the form Game.
I've tried unifying them in just one string and pass just one variabe to Game form, without success.
public partial class Game : Form
{
static int nPlayers = 4;
static List<Player> players = new List<Player>();
public string name = "";
private void button3_Click(object sender, EventArgs e)
{
using (newPlayer np = new newPlayer())
{
if (np.ShowDialog() == DialogResult.OK)
{
this.name = np.TheValue;
}
}
MessageBox.Show("Welcome " + name + "!");
}
and then:
public partial class newPlayer : Form
{
public string name = "";
public string TheValue
{
get { return this.name; }
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
if (comboBox1.SelectedIndex > -1)
{
this.name = textBox1.Text + comboBox1.SelectedIndex.ToString();
MessageBox.Show(newPlayer.name);
this.Close();
} else
{
MessageBox.Show("Write your name and choose a color!");
}
} else
{
MessageBox.Show("Write your name and choose a color!");
}
}
On the MessageBox of newPlayer it appears correctly like "Name1", for example. But on the MessageBox of Game, it appears empty. Can someone help, please?
You have forgotten to set the DialogResult when closing the form.
Try this:
this.DialogResult = DialogResult.OK;
this.Close();
If I were writing this code I might have done it more like this:
Game:
public partial class Game : Form
{
public Game()
{
InitializeComponent();
}
private string _playerName = "";
private void button3_Click(object sender, EventArgs e)
{
using (NewPlayer np = new NewPlayer())
{
if (np.ShowDialog() == DialogResult.OK)
{
_playerName = np.PlayerName;
MessageBox.Show($"Welcome {_playerName}!");
}
}
}
}
NewPlayer:
public partial class NewPlayer : Form
{
public NewPlayer()
{
InitializeComponent();
}
private string _playerName = "";
public string PlayerName
{
get { return _playerName; }
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" && comboBox1.SelectedIndex > -1)
{
_playerName = $"{textBox1.Text}{comboBox1.SelectedIndex}";
MessageBox.Show(_playerName);
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show("Write your name and choose a color!");
}
}
}

Passing object from one windows form to another

I have two windows forms in my application. First one is Main form and the second one is lookup form. I'm trying to open lookup form from the main form in a text box key leave event and then I'm opening the lookup form. My lookup form has a data grid view and I' loading it in the form load event of the lookup form. I'm reading my selected value on the grid view of the lookup window to an object. I want to close the lookup window as soon as I read the values of the selected row to the object and I want to pass it to the main form? How can I do that?
This is what I have done.
In the main form.
LookupModelType="";
if (e.KeyCode.Equals(Keys.F3))
{
foreach (Form frm in Application.OpenForms)
{
if (frm is FormControllers.Lookup)
{
if (frm.WindowState == FormWindowState.Minimized)
{
frm.WindowState = FormWindowState.Normal;
frm.Focus();
return;
}
}
}
LookupModelType = "Product";
FormControllers.Lookup newLookUp = new FormControllers.Lookup(LookupModelType);
newLookUp.ShowDialog(this);
}
In the lookup window
private string GridType = "";
public Lookup(String LookupModelType)
{
InitializeComponent();
this.GridType = LookupModelType;
}
private void Lookup_Load(object sender, EventArgs e)
{
if (GridType == "Product")
{
using(DataControllers.RIT_Allocation_Entities RAEntity = new DataControllers.RIT_Allocation_Entities())
{
dgvLookup.DataSource = RAEntity.TBLM_PRODUCT.ToList<DataControllers.TBLM_PRODUCT>();
}
}
dgvLookup.ReadOnly = true;
}
private void dgvLookup_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
{
return;
}
int index = e.RowIndex;
dgvLookup.Rows[index].Selected = true;
}
you can do it like blow :
in the Main form :
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F3)
{
LookupForm look = new LookupForm();
var result = look.ShowDialog();
if(result == DialogResult.OK)
{
MessageBox.Show(look.data.ToString());
}
}
}
and in the look up form you have to declare 1 variable and fill whenever cell clicked
public partial class LookupForm : Form
{
public object data = new object();
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
data = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
of course, for better performance, you can declare the variable in specific type
To share data between Parent Child forms using events, here are the things needed:
A public custom event args class to share data.
Child form to have a event.
In your parent form whenever you create an instance of child, you
need to register eventhandlers
Please note that the code below is just a demo code and you will need to add null checks etc. to make it "robust".
Custom event args below
public class ValueSelectedEventArgs : EventArgs
{
public object Value { get; set; }
}
Your lookup form should have the following event declared:
public event EventHandler ValueSelected;
protected virtual void OnValueSelected(ValueSelectedEventArgs e)
{
EventHandler handler = ValueSelected;
if (handler != null)
{
handler(this, e);
}
// if you are using recent version of c# you can simplyfy the code to ValueSelected?.Invoke(this, e);
}
In my case I am firing the event on listbox selected index change and closing the form as well. Code for it:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var i = this.checkedListBox1.SelectedIndex;
ValueSelectedEventArgs args = new ValueSelectedEventArgs();
args.Value = i;
OnValueSelected(args);
this.Close();
}
Finally in the parent form you have to register for the eventhandler
private void textBox1_Leave(object sender, EventArgs e)
{
lookup myLookup = new lookup();
myLookup.ValueSelected += MyLookup_ValueSelected;
myLookup.Show();
}
private void MyLookup_ValueSelected(object sender, EventArgs e)
{
textBox2.Text = (e as ValueSelectedEventArgs).Value.ToString();
}
I personal like to add dynamically the lookup window, and I do something like this:
//examble object
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// the value which you want to get from datagridview
private Person _selectedValue;
// the datagridview datasource, which you neet to set
private IEnumerable<Person> _gridDataSource =
new List<Person>()
{
new Person {FirstName="Bob",LastName="Smith" },
new Person {FirstName="Joe",LastName="Doe"}
};
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.F3)
{
var btnOk = new Button() { Text = "Ok", Anchor= AnchorStyles.None };
var btnCancel = new Button() { Text = "Cancel",Anchor= AnchorStyles.Right };
var dg = new DataGridView();
var bs = new BindingSource();
bs.DataSource = _gridDataSource;
dg.DataSource = bs;
dg.Dock = DockStyle.Fill;
dg.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//setup a layout wich will nicely fit to the window
var layout = new TableLayoutPanel();
layout.Controls.Add(dg, 0, 0);
layout.SetColumnSpan(dg, 2);
layout.Controls.Add(btnCancel, 0, 1);
layout.Controls.Add(btnOk, 1, 1);
layout.RowStyles.Add(new RowStyle(SizeType.Percent));
layout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.Dock = DockStyle.Fill;
//create a new window and add the cotnrols
var window = new Form();
window.StartPosition = FormStartPosition.CenterScreen;
window.Controls.Add(layout);
// set the ok and cancel buttons of the window
window.AcceptButton = btnOk;
window.CancelButton = btnCancel;
btnOk.Click += (s, ev) => { window.DialogResult = DialogResult.OK; };
btnCancel.Click += (s, ev) => { window.DialogResult = DialogResult.Cancel; };
//here we show the window as a dialog
if (window.ShowDialog() == DialogResult.OK)
{
_selectedValue =(Person) bs.Current;
MessageBox.Show(_selectedValue.FirstName);
}
}
}

Generalizing the form calling in a button event

I usually call this piece of code to show a form whenever a button is clicked.
private frmSelection _frmSelection;`
private void _frmSelection_FormClosing(object sender, FormClosingEventArgs e)
{
_frmSelection = null;
}
private void changeFeedOrderToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_frmSelection == null)
{
_frmSelection = new frmSelection();
_frmSelection.FormClosing += _frmSelection_FormClosing;
_frmSelection.WindowState = FormWindowState.Minimized;
_frmSelection.Show();
_frmSelection.WindowState = FormWindowState.Normal;
}
else
{
_frmSelection.WindowState = FormWindowState.Minimized;
_frmSelection.WindowState = FormWindowState.Normal;
}
}
If the form is already open it will show the already opened instance instead of creating new instance. It is working fine.
But my problem is i need to copy paste and change the form name whenever i am adding a new form.
How it can be generalized and added to
Helper
class?
Something like this:
public sealed class ReusableFormContainer<T> : IDisposable
where T : Form, new()
{
private bool isDisposed;
private void HandleFormClosing(object sender, FormClosingEventArgs e)
{
Form = null;
}
public T Form { get; private set; }
public void Show()
{
if (isDisposed)
{
throw new ObjectDisposedException(null);
}
if (Form == null)
{
Form = new T { WindowState = FormWindowState.Minimized };
Form.FormClosing += HandleFormClosing;
Form.Show();
}
else
{
Form.WindowState = FormWindowState.Minimized;
}
Form.WindowState = FormWindowState.Normal;
}
public void Dispose()
{
// IDisposable.Dispose is implemented to handle cases, when you want to close
// wrapped form using code
if (!isDisposed)
{
Form?.Dispose();
isDisposed = true;
}
}
}
Usage:
// must be initialized somewhere in constructors
private readonly ReusableFormContainer<FormA> container_A;
private readonly ReusableFormContainer<FormB> container_B;
private void button1_Click(object sender, EventArgs e)
{
container_A.Show();
}
private void button2_Click(object sender, EventArgs e)
{
container_B.Show();
}
The following code might do what you want. Just thought about to use the Application functions because those can cover all forms that are on thread.
public partial class Form1 : Form
{
public int i;
private Form1 _frmSelection;
public Form1()
{
InitializeComponent();
i = Application.OpenForms.Count;
}
private void _frmSelection_FormClosing(object sender, FormClosingEventArgs e)
{
_frmSelection = null;
}
private void button1_Click(object sender, EventArgs e)
{
if (_frmSelection == null)
{
_frmSelection = new Form1();
_frmSelection.FormClosing += _frmSelection_FormClosing;
_frmSelection.WindowState = FormWindowState.Minimized;
_frmSelection.WindowState = FormWindowState.Normal;
_frmSelection.Show();
if (Application.OpenForms.Count > 1)
{
_frmSelection.Text = Application.OpenForms[i].Text + " and going";
}
}
else
{
_frmSelection.WindowState = FormWindowState.Minimized;
_frmSelection.WindowState = FormWindowState.Normal;
}
}
}

select the tab opened by a button click

I have a form with a button in it. If i click the button another form opens. If I return to the parent form with the help of tab and click the same button again it does nothing.
Here is my code:
private void pictureBox1_Click(object sender, EventArgs e)
{
form wadd = new form(this);
if ((IsFormAlreadyOpen(typeof(form))) == null)
{
wadd.MdiParent = Form1.ActiveForm;
wadd.Show();
}
}
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
private void Form1_MdiChildActivate(object sender, EventArgs e)
{
if (this.ActiveMdiChild == null)
tabForms.Visible = false;
// If no any child form, hide tabControl
else
{
this.ActiveMdiChild.WindowState = FormWindowState.Maximized;
// Child form always maximized
// If child form is new and no has tabPage,
// create new tabPage
if (this.ActiveMdiChild.Tag == null)
{
// Add a tabPage to tabControl with child
// form caption
TabPage tp = new TabPage(this.ActiveMdiChild.Text);
tp.Tag = this.ActiveMdiChild;
tp.Parent = tabForms;
tabForms.SelectedTab = tp;
this.ActiveMdiChild.Tag = tp;
this.ActiveMdiChild.FormClosed += new FormClosedEventHandler(ActiveMdiChild_FormClosed);
}
else
{
tab();
}
if (!tabForms.Visible) tabForms.Visible = true;
}
}
public void tab()
{
for (int i = 0; i < tabForms.TabCount; i++)
{
if (tabForms.TabPages[i].Text == this.ActiveMdiChild.Text.ToString())
{
tabForms.SelectedTab = tabForms.TabPages[i];
break;
}
}
}
private void ActiveMdiChild_FormClosed(object sender, FormClosedEventArgs e)
{
//Destroy the corresponding Tabpage when closing MDI child form
if (tabForms.HasChildren)
{
((sender as Form).Tag as TabPage).Dispose();
}
//If no Tabpage left
else if (!tabForms.HasChildren)
{
tabForms.Visible = false;
}
}
private void tabForms_SelectedIndexChanged(object sender, EventArgs e)
{
if ((tabForms.SelectedTab != null) && (tabForms.SelectedTab.Tag != null))
(tabForms.SelectedTab.Tag as Form).Select();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (!tabForms.HasChildren)
{
Application.Exit();
}
}
The result I want is when I click the button again the tab should gets focused to this form rather than opening new form which is not permissable.
I think you'd want something like this:
public Form FormOpened<T>()
{
foreach (Form form in Application.OpenForms)
if (typeof(T) == form.GetType())
return form;
return null;
}
You could then use it like this:
form f = (form)FormOpened<form>();
if (f2 == null)
{
f2 = new form();
f2.MdiParent = this;
f2.Show();
}
else
{
f2.Focus();
}
Tell me if you need any help.
You want something like this I believe:
form wadd;
private void pictureBox1_Click(object sender, EventArgs e)
{
if (wadd == null)
{
wadd = new form(this);
}
wadd.MdiParent = Form1.ActiveForm;
wadd.Show();
}
You just have the logic backwards. If there is no form open, then create it then open it. If there is a form already then just use it.

Categories

Resources