Why does MessageBox be run several times in this code? - c#

I'm a newbie in programming and writing codes.
I have a very simple form with 6 buttons.
When I click on every button only the sender's text got Magenta.
But Button3 do a further work and that's opening a "Hello" messageBox.
The problem is when I click on Button3, it shows "hello" string 4 times. Why?
I think and expect it show it just once no more.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Typhok(object sender, EventArgs e)
{
foreach (Control x in this.Controls)
{
if (x.Equals(sender))
x.ForeColor = Color.Magenta;
else
x.ForeColor = Color.Black;
}
b3.Click += new EventHandler(Popup);
}
private void Popup(object sender, EventArgs e)
{
MessageBox.Show("hello!");
}
}
UPDATE: Can anyone explain to me why that original code had that problem?

Register event handler in constructor, not in Typhok method. The final code should look like:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
b3.Click += new EventHandler(Popup);
}
private void Typhok(object sender, EventArgs e)
{
foreach (Control x in this.Controls)
{
if (x.Equals(sender))
x.ForeColor = Color.Magenta;
else
x.ForeColor = Color.Black;
}
}
private void Popup(object sender, EventArgs e)
{
MessageBox.Show("hello!");
}
}

Related

Manipulating similar objects in a form using another form

I am new to C# and I want to utilize the forms with one another.
I have 2 forms. (1)MMCMLibrary_home and (2)MMCMLibrary_reserve.
In this project, I'm in the stage of changing the label background colors in Form 1 but can't seem to utilize Form 2 to process it.
These are my necessary codes so far:
FORM 1
namespace MMCM_Library
{
public partial class MMCMLibrary_home : Form
{
public static MMCMLibrary_home instance;
//DCR1 Labels
public Label lbl1_1;
public Label lbl1_2;
public Label lbl1_3;
public Label lbl1_4;
public MMCMLibrary_home()
{
InitializeComponent();
instance = this;
lbl1_1 = lblDCR1_9;
lbl1_2 = lblDCR2_11;
lbl1_3 = lblDCR1_1;
lbl1_4 = lblDCR1_3;
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve();
reserveDCR1.Show();
}
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve();
reserveDCR2.Show();
}
public void btnDCR3_Click(object sender, EventArgs e)
{
var reserveDCR3 = new MMCMLibrary_reserve();
reserveDCR3.Show();
}
public void btnDCR4_Click(object sender, EventArgs e)
{
var reserveDCR4 = new MMCMLibrary_reserve();
reserveDCR4.Show();
}
}
}
FORM 2
when I click any reserve now button in form 1 it will open form 2. However, if I pick a radio button, the background change will always be applied to Discussion Room 1 even I reserved for discussion room 2
namespace MMCM_Library
{
public partial class MMCMLibrary_reserve : Form
{
public static MMCMLibrary_reserve instance;
public MMCMLibrary_reserve()
{
InitializeComponent();
instance = this;
}
private void MMCMLibrary_reserve_Load(object sender, EventArgs e)
{
}
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged_1(object sender, EventArgs e)
{
}
private void btnDCR1_Click(object sender, EventArgs e)
{
}
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
}
}
}
Can you help me to device an efficient way to solve this. Can you also suggest a database method suitable for my beginner project.
You've said that:
the background change will always be applied to Discussion Room 1
Well, yes. It seems you don't pass specific object into Form2. There's strightforward:
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
So you'll be always changing backcolor of lbl1_1 of your Form1. What needs to be done is to indicate which room has been selected. You can assign room after you click the button by passing the int parameter:
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve(1);
reserveDCR1.Show();
}
or:
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve(2);
reserveDCR2.Show();
}
Then, in Form2, at the very top, add something like:
int room; to be able to assign the room number in Form2:
public MMCMLibrary_reserve(int roomNumber)
{
InitializeComponent();
room = roomNumber;
instance = this;
}
And then you could just select room you clicked, by:
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
if(room == 1)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
else if(room == 2)
{
MMCMLibrary_home.instance.lbl1_2.BackColor = System.Drawing.Color.Red;
}
else if(room == 3)
{
MMCMLibrary_home.instance.lbl1_3.BackColor = System.Drawing.Color.Red;
}
else if(room == 4)
{
MMCMLibrary_home.instance.lbl1_4.BackColor = System.Drawing.Color.Red;
}
}
else if(radioButton2.Checked)
{
//etc.
}
else if(radioButton3.Checked)
{
//etc.
}
else if(radioButton4.Checked)
{
//etc.
}
}
I think that was the problem. Try it and let us know.

Is there a way to make a panel move slowly in Visual Studio using C#?

I have coded a form where a panel moves when a button is clicked to the height of the clicked button. However, I want to make the panel move slowly instead of instantly.
This is the code I have used:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MovePanel(btn1);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void MovePanel(Control c)
{
Panel.Height = c.Height;
Panel.Top = c.Top;
}
private void btn1_Click(object sender, EventArgs e)
{
MovePanel(btn1);
}
private void btn2_Click(object sender, EventArgs e)
{
MovePanel(btn2);
}
private void btn3_Click(object sender, EventArgs e)
{
MovePanel(btn3);
}
}
I would really like to see a timer-based solution from scratch.
In the meantime, you might check out something like dot-net-transitions, available on NuGet.
using Transitions;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btn1.Click += btn_Click;
btn2.Click += btn_Click;
btn3.Click += btn_Click;
MovePanel(btn1);
}
private void MovePanel(Control c)
{
var t = new Transition(new TransitionType_Linear(500));
t.add(Panel, "Height", c.Height);
t.add(Panel, "Top", c.Top);
t.run();
}
private void btn_Click(object sender, EventArgs e)
{
MovePanel(sender as Control);
}
}

How can you hide a button from another form

I have a C# project that has 2 forms. The first has 3 buttons. I need to be able from the second form to hide 2 (button1 and button2 )buttons with a checkbox, and I don't know how to call the buttons from the first form.
this is form1
namespace test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
and this is Form2
namespace test1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
?????????
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.checkB = checkBox1.Checked;
Properties.Settings.Default.Save();
}
}
}
Another option is to pass the form as the "owner" in the Show() command:
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show(this); // pass Form1 reference in to our instance of Form2
}
In Form2, cast the Owner property back to Form1 so you can access it (assuming you've changed the modifiers property of the buttons to public as already suggested):
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
Form1 f1 = (Form1)this.Owner;
f1.button1.Visible = false; // or whatever your buttons are called
}
}
This is almost exactly what I had posted previously...you need to change the Modifiers property of the buttons so they are public and can be seen from Form2.
this is the final version that works in my case thanks to those who answered my question and helped me to get this answer
Form1
namespace test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 frm = new Form2();
frm.checkBox1.Checked = Properties.Settings.Default.checkB;
if (frm.checkBox1.CheckState == CheckState.Checked)
{
button1.Visible = false;
}
}
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show(this);
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
}
}
}
Form2
namespace test1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
Form1 f1 = (Form1)this.Owner;
f1.button1.Visible = false;
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.checkB = checkBox1.Checked;
Properties.Settings.Default.Save();
}
}
}
The buttons and checkBox are set to Modifiers - Public
you need to make the buttons on the first form public and then you can access them once you create a instance of the first form you will need to pass that form to the second form.
Might want to look into building an event that fires from one form and gets handled by the other form to disable the button.

How to create Dialog Box with Radio Buttons and return Value

I have a List of Objects. What I want to do:
Build a Dialog Box which shows a Radio Button for each element in the given List and returning the selected element/value by clicking on OK-Button.
Thanks in Advance.
Here is a quick example of creating your own form and getting a value from it.
Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
frmTest frmTest = new frmTest();
DialogResult dr = frmTest.ShowDialog();
if(dr == System.Windows.Forms.DialogResult.OK)
{
string value = frmTest.GetValue();
MessageBox.Show(value);
}
}
}
Form1 View:
public partial class frmTest : Form
{
private string _value { get; set; }
public frmTest()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
this._value = radioButton.Text; // Assign the radio button text as value Ex: AAA
}
public string GetValue()
{
return this._value;
}
}
You have to make sure that all radio buttons are using radioButton_CheckedChanged for the CheckedChanged event.
Form2 View:
Output:
build your own form and add a public variable "a string for example" called "Result"
public partial class YourDialog:Form
{
public string Result = "";
public YourDialog()
{// add all the controls you need with the necessary handlers
//add the OK button with an "On Click handler"
}
private void OK_Button_Click(object sender, EventArgs e)
{
//set the Result value according to your controls
this.hide();// will explain in the main form
}
}
// in your main form
private string GetUserResult()
{
YourDialog NewDialog = new YourDialog();
NewDialog.ShowDialog();//that's why you only have to hide it and not close it before getting the result
string Result = NewDialog.Result;
NewDialog.Close();
return Result;
}
OOps! I came back just to see there are already 2 answers! How ever, I want to post my version, which can build controls according to list of strings:
//dialog form
public partial class frmDialogcs : Form
{
public string selectedString;
//keep default constructor or not is fine
public frmDialogcs()
{
InitializeComponent();
}
public frmDialogcs(IList<string> lst)
{
InitializeComponent();
for (int i = 0; i < lst.Count; i++)
{
RadioButton rdb = new RadioButton();
rdb.Text = lst[i];
rdb.Size = new Size(100, 30);
this.Controls.Add(rdb);
rdb.Location = new Point(20, 20 + 35 * i);
rdb.CheckedChanged += (s, ee) =>
{
var r = s as RadioButton;
if (r.Checked)
this.selectedString = r.Text;
};
}
}
private void btnOK_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
}
//in main form
private void button1_Click(object sender, EventArgs e)
{
var lst = new List<string>() { "a", "b", "c" };
frmDialogcs dlg = new frmDialogcs(lst);
if (dlg.ShowDialog() == DialogResult.OK)
{
string selected = dlg.selectedString;
MessageBox.Show(selected);
}
}

Forward a KeyPress-event

I have a TextBox and would like to forward a KeyPress-event from another Form.
So far I have my Form:
private readonly Action<KeyPressEventArgs> m_KeyPress;
public KeyboardForm( Action<KeyPressEventArgs> keyPress )
{
m_KeyPress = keyPress;
}
protected override void OnKeyPress( KeyPressEventArgs e )
{
m_KeyPress( e );
base.OnKeyPress( e );
}
And a derived TextBox, which initializes the Form:
var keyboardForm = new KeyboardForm( OnKeyPress );
keyboardForm.Show();
Now, the OnKeyPress-method gets called as expected (of the Form, then of the TextBox). But nevertheless nothing happens ... when I press 'a' I expected an 'a' to appear in my TextBox ...
Does anyone have an idea what's the problem here?
It is not working with KeyDown, too, and attaching to the regular exposed event KeyPress does not help me either. I think, that the problem is the explicit call of OnKeyPress. Is it allowed?
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 f = new Form2();
f.mEvent += new Form2.TestEvent(f_mEvent);
f.Show();
}
void f_mEvent(KeyPressEventArgs e)
{
textBox1.Text += e.KeyChar;
}
}
Form2:
public partial class Form2 : Form
{
public delegate void TestEvent(KeyPressEventArgs e);
public event TestEvent mEvent;
public Form2()
{
InitializeComponent();
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (mEvent != null)
{
mEvent(e);
}
base.OnKeyPress(e);
}
}
This should do what you want. Make the text of the buttons on the Keyboard Form based on the SendKey characters. For example, if you want lower case a, just put "a" for the keyboard button text. If you want a backspace button, just put "backspace" as the text of the button. All the keyboard buttons Click events can register for the ButtonClick function
Keyboard Form:
public partial class KeyboardForm : Form
{
public delegate void ButtonPressed(string keyPressed);
public event ButtonPressed ButtonPressedEvent;
public KeyboardForm()
{
InitializeComponent();
}
private void ButtonClick(object sender, EventArgs e)
{
Button button = sender as Button;
if (button != null)
{
if ((ButtonPressedEvent != null))
{
ButtonPressedEvent("{"+button.Text+"}");
}
}
}
}
Form with textbox that the user types things into:
public partial class Form1 : Form
{
private KeyboardForm mKeyboardForm = new KeyboardForm();
private bool mIsKeyboardCode = false;
public Form1()
{
InitializeComponent();
mKeyboardForm.ButtonPressedEvent += new KeyboardForm.ButtonPressed(KeyboardFormButtonPressedEvent);
}
void KeyboardFormButtonPressedEvent(string keyPressed)
{
mIsKeyboardCode = true;
textBox1.Focus();
SendKeys.SendWait(keyPressed.ToString());
mKeyboardForm.Focus();
mIsKeyboardCode = false;
}
private void TextBoxKeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.ControlKey)
{
if (!mKeyboardForm.Visible)
{
mKeyboardForm.Show(this);
e.Handled = true;
}
}
else if (!mIsKeyboardCode)
{
mKeyboardForm.Hide();
}
}
}
Note: I did not use an extended textbox with a form inside of it. I dont think its a good design to have a form be shown/hidden from a custom textbox.
From this answer: https://social.msdn.microsoft.com/Forums/windows/en-US/92215fdf-8be0-4e3a-b796-dd7c0f131666/keypreview-true-how-do-you-then-detect-enterreturn?forum=winforms
If you have a button on your form that is catching the Enter key presses, you can allow the enter key to be handled as a normal KeyPreview key with the following code:
void button_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
e.IsInputKey = true;
}
}

Categories