How do I refresh a form after it is shown again? - c#

I am creating a program in C# Windows Form Application.
Let me give you a scenario of what I am doing:
Log into the program (login system)
The program will determine the user's permission value (let's say I'm 3)
Depending on the permission value, the main menu will show buttons
3a. If the user has permission value greater than 2, user will view all buttons
3b. If the user has permission value less than 2, user will see only 1 button
When I logout, I am using .hide to hide the main menu and showing the login form again.
I log in another user (with permission value = 1)
All the buttons will show, not just only 1 like it should be.
Does anyone know how to "redo" the main menu after logging in, depending on permission value?

Maybe this?
const int firstButtonY = 20;
const int padding = 20;
int currentY = firstButtonY;
foreach (var control in this.Controls)
{
if (control.GetType() != typeof(System.Windows.Forms.Button))
continue;
var curButton = (Button) control;
if (!curButton.Visible)
continue;
curButton.Top = currentY;
currentY += padding + curButton.Height;
}

Instead of open new instance (in my case, Form3) in Form1 in Form1_Load
frm3 = new Form3(this);
and show after specified event trigger
frm3.Show();
and cancel the Form3_Closing
private void Form3_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
We do like this for every event triggered
frm3 = new Form3(this);
frm3.Show();
and comment the create new instance in Form1_Load
//frm3 = new Form3(this);
and comment the Hide form3 part
private void Form3_FormClosing(object sender, FormClosingEventArgs e)
{
//e.Cancel = true;
//this.Hide();
}
because frm3.Show() after the form3 this.Hide() WON'T triggered
private void Form3_Load(object sender, EventArgs e)

Related

Show Form side-by-side owner Form

I have a form. If someone presses a button, I want to show a second form "attached" to the original form, meaning that its left side is at the right side of the original form and they have the same height. In other words: they touch each other.
An answer seems to be Open Form next to Parent Form
However, there is a gap between the images. I want them to be exactly next to each other
main form:
private void ShowOtherForm()
{
using (var form = new OtherForm())
{
var dlgResult = form.ShowDialog(this);
ProcessDlgResult(dlgResult);
}
}
Other form, event handler Load
private void FormLoad(object sender, EventArgs e)
{
// show this form attached to the right side of my owner:
this.Location = new Point(this.Owner.Right, this.Owner.Top);
this.Height = this.Owner.Height;
}
Try to use ClientSize and Location
private void Form2_Load(object sender, EventArgs e)
{
var owner = this.Owner;
Location = new Point(owner.Location.X + owner.ClientSize.Width, owner.Location.Y);
Height = owner.Height;
}

Controlling an objects property from a form to another using a button C# [duplicate]

This question already has an answer here:
Interaction between forms — How to change a control of a form from another form?
(1 answer)
Closed 4 years ago.
Sorry, I'm a C# beginner
I am trying to make a button on Form 4 that will make change a property of an object in Form 3.
This case, every time I press button 1 on Form 4, the label on Form 3 will say that "You pressed button 1", Same thing on the button 2.
I added this on Form 4.
public partial class Form4 : Form
{
public bool buttonchecked;
private void button1_Click_1(object sender, EventArgs e)
{
buttonchecked = true;
}
private void button2_Click_1(object sender, EventArgs e)
{
buttonchecked = false;
}
And this is what i put on Form 3:
public void label2_Click(object sender, EventArgs e)
{
Form4 form4 = new Form4(); //add
if (form4.buttonchecked == true)
{
label2.Text = "You pressed button 1";
}
else
{
label2.Text = "You pressed button2";
My label2 text is always set to "You pressed button2" but I didn't
I added a code that closes the current form and Opens the other form, maybe this is causing the problem?
this is from the Form 3
this.Hide();
Form4 f4 = new Form4();
f4.ShowDialog();
and this is from the Form 4
this.Hide();
Form3 frm3 = new Form3();
frm3.ShowDialog();
Is there anything something I'm doing wrong?
There are a few issues with your code:
On Form3, why are you handling the label2_click button? This event is fired when you click on a label. If the Text property of your label is an empty string, you won't even see the label in order to be able to click it.
This code:
Form4 form4 = new Form4();
if (form4.buttonchecked == true)
// etc
is not logically correct, because you are creating a Form4 instance and then you're checking the value of it's public field (buttonchecked) without displaying the form. The default value of a boolean variable is false, so the control will always hit the else branch. That's the reason you're always getting the "You pressed button2" message.
One correct way to do this using your code is the following:
On Form3:
var form4 = new Form4();
var result = form4.ShowDialog();
if (result == DialogResult.OK)
{
label2.Text = "You pressed button 1";
}
else
{
label2.Text = "You pressed button 2";
}
On Form4:
public partial class Form4 : Form
{
public bool buttonchecked;
private void button1_Click_1(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
private void button2_Click_1(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
}
The ShowDialog() method will display the Form4 and will block the Form3 execution. On Form4 you set a DialogResult based on the button you pressed and you return that result to the calling form (Form3). Based on that result, you can take a decision.
That solution will do the job, but it has one issue: you can't play with both forms in parallel because of the Dialog constraint (when you open the Form4 from Form3, you have to close it in order to reach Form3 again, you can't play with both of them in the same time).
So here's a new (clean) solution that solves this problem:
On Form3 in Designer Mode, click on the label2 -> Properties -> Modifiers -> Public. In that way you can access the label2 from other forms.
On Form4, place the follwing code:
public partial class Form4 : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
var form3 = Application.OpenForms["Form3"];
form3.label2.Text = "You pressed button 1";
}
private void button2_Click_1(object sender, EventArgs e)
{
var form3 = Application.OpenForms["Form3"];
form3.label2.Text = "You pressed button 2";
}
}
Note: on that solution, Form3 needs to be open before Form4, otherwise Application.OpenForms["Form3"] will return null or it will throw an exception.
If you have any further issues, don't hesitate to leave a comment.

Enabling Button in Messagebox with timer

I have a message box that pops up when a user click a button. when user click yes it's run an insert function.
what i want is to add or start a count down when a messagebox pop up, the default yes button was disabled. and after 5 second the yes button, become enable and ready to click by user.
if (MessageBox.Show("log", "test", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
insert();
}
As suggested in the comment, you need to have your own implementation for this functionality. Below is partial code that you will need to modify normal form to make it appear like dialogue box:
Add new Form to your project. Open the porperties tab. Set properties as give below in point 2.
Modify form in designer to change following properties to given values:
this.AcceptButton = this.btnYes;//To simulate clicking *ENTER* (Yes)
this.CancelButton = this.button2; //to close form on *ESCAPE* button
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
//FROM CODEPROJECT ARTICLE LINK
this.ShowInTaskBar = false;
this.StartPosition = CenterScreen;
Add a timer to form. Set its interval to 5000 (5 seconds). Write code to start timer on Shown event of form:
private void DialogBox_Shown(object sender, EventArgs e)
{
timer1.Start();
}
Handle ticking of Timer:
public DialogBox()
{
InitializeComponent();
//bind Handler to tick event. You can double click in
//properrties>events tab in designer
timer1.Tick += Timer1_Tick;
}
private void Timer1_Tick(object sender, EventArgs e)
{
btnYes.Enabled = true;
timer1.Stop();
}
Set Yes button handler:
private void btnYes_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Yes;
}
From where you are showing this custom message box, you can check if Yes or No is clicked as follows:
var d=new DialogBox();
var result=d.ShowDialog();
if(result==DialogResult.Yes)
//here you go....

C# esc key not being captured when used on a form with a timer

The application I'm working on keeps track of bowling scores during tournaments. In it, there's a data entry sheet and a scoreboard. The data entry sheet has a button on which to click to launch the scoreboard form in a different thread.
private void pict_projector_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new
System.Threading.ThreadStart(this.openScoreboard));
t.Start();
}
private void openScoreboard()
{
frm_scoreboard frm = new frm_scoreboard();
frm.TourID = this.TourID;
frm.NightID = night_id;
Application.Run(frm);
}
On the scoreboard form I have a timer (threaded system.Timer) that ticks every second and checks if it's been 15 seconds before switching the scoreboards TableLayoutPanel to reflect the next playing divisions scores.
private void ttmr_switch_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
cnt_ticks++;
if (cnt_ticks == 15)
{
cnt_ticks = 0;
ttmr_switch.Enabled = false;
switchBoard();
}
}
On the same form (scoreboard) there's a "maximize" button which renders the form fullscreen. To exit fullscreen, I want the user to press Esc. Here is where the problem comes in.
private void frm_scoreboard_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Escape)
{
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.WindowState = FormWindowState.Normal;
pict_fullscreen.Visible = true;
}
}
The KeyDown event never gets triggered... and I lose control of the form.
After banging my head against a wall for a while, I decided to bring this to you all. Any idea how to resolve this?
Did you set the KeyPreview option of the form to true?
more information on msdn

Disabling double click on winform button

I have developed a windows form application in C#.Net. There are multiple forms in the application. Main form say frmA has a push button say btnA. On clicking btnA, new form say frmB is opened and frmA goes behind frmB. frmB also has a push button say btnB and position (location) of btnB on frmB is exactly same as that of btnA on frmA. On clicking btnB, some different actions take place.
Now my problem is some of application users double click on btnA. I get two single clicks back to back. On first single click on btnA, frmB is opened with btnB. Second single click is immediately executed on btnB and in effect users don't even get to see frmB.
My constraint is I cannot change locations of buttons on either forms. Is there anyway I can handle this problem?
Set btnB.Enabled to false and use the following code. This will delay the possibility to click the button for half a second.
public partial class frmB : Form
{
private Timer buttonTimer = new Timer();
public frmB()
{
InitializeComponent();
buttonTimer.Tick += new EventHandler(buttonTimer_Tick);
buttonTimer.Interval = 500;
}
private void frmB_Shown(object sender, EventArgs e)
{
buttonTimer.Start();
}
void buttonTimer_Tick(object sender, EventArgs e)
{
btnB.Enabled = true;
buttonTimer.Stop();
}
}
Just try to fire new form into different position.
As i've understood user is firing frmB on first click
and pressing btnB on "second click"
It's not double click.
It's two different clicks
try something like that:
Form2 form=new Form2();
form.StartPosition = FormStartPosition.Manual;
form.Location=new Point(0, 10);
form.Show();
I would do some trick, What about changing the cursor position. Once user click on btnA cursor point will be shifted a little so the second click will not hit the btnB.
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
Cursor.Clip = new Rectangle(this.Location, this.Size);
disable it on the first click enable it when the user open again the forma or it come from forma to form b
this.button.enable=false;
immediately after pressing the button.
and write again in the constructor of forma
this.button.enable=true;
I agree that this UI is not friendly but if you absolutely cannot change the position of the buttons or the open position of the second form then you need to stop the second click causing the closure of frmB. Easiest way would be to build in a delay upon opening formB e.g.
public partial class FormB : Form
{
public FormB()
{
InitializeComponent();
Thread.Sleep(2000);
}
}
You can use IMessageFilter to detect WM_LBUTTONDOWN messages and suppress them if they occur within a certain time threshold:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Application.AddMessageFilter(new DoubleClickSuppressser());
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.StartPosition = FormStartPosition.Manual;
f2.Location = this.Location;
f2.Show();
}
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Console.WriteLine("listBox1 DoubleClick");
}
}
public class DoubleClickSuppressser : IMessageFilter
{
private int difference;
private DateTime Last_LBUTTONDOWN = DateTime.MinValue;
private const int WM_LBUTTONDOWN = 0x201;
public bool PreFilterMessage(ref Message m)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
if (Control.FromHandle(m.HWnd) is Button)
{
if (!Last_LBUTTONDOWN.Equals(DateTime.MinValue))
{
difference = (int)DateTime.Now.Subtract(Last_LBUTTONDOWN).TotalMilliseconds;
Last_LBUTTONDOWN = DateTime.Now;
if (difference < System.Windows.Forms.SystemInformation.DoubleClickTime)
{
return true;
}
}
Last_LBUTTONDOWN = DateTime.Now;
}
break;
}
return false;
}
}
Note that I've specifically disabled Double Clicking only for Buttons with the Control.FromHandle() check. This will allow double clicks to work on other controls such as ListBoxes, etc...
In your own class, inherit the base control and use the .SetStyle() method to disable the double-click. The below code isn't for a Button, but it should work the same:
public class MOBIcon : PictureBox
{
public MOBIcon() : base()
{
this.SetStyle(ControlStyles.StandardDoubleClick, false);
}
}
The problem with enabling and disabling the button is that if the code you have in the click event runs so fast that the button gets enabled before the second click of the double click action (some users don't understand that it only takes 1 click) so here is my solution.
private const int waittime = 2;
private DateTime clickTime = DateTime.Now;
private void cmd_TimeStamp_Click(object sender, EventArgs e)
{
if ((DateTime.Now - clickTime).Seconds < waittime)
return;
else
clickTime = DateTime.Now;
try
{
cmd_TimeStamp.Enabled = false;
//Do some stuff in here
}
catch (Exception ex)
{
//Show error if any
MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
cmd_TimeStamp.Enabled = true;
}
}

Categories

Resources