Class variable resets after the class is instantiated - c#

So i'm writing an application that has a log in screen followed by a menu screen.
The menu has different buttons enabled for each level of user. To do this when the user logs in, an int is assigned, letting the application know what level the user is logged on and which buttons/reports to enable.
The problem I'm having is when the report is closed and the menu is called up again, the variable is reset back to the default admin level.
Menu M = new Menu(Permission);
M.Show();
this.Hide();
This code is used to pull up the menu from the log in, the int is being passed to a constructor.
public Menu(string Permission)
{
InitializeComponent();
AccessLevel = int.Parse(Permission);
LockKeys();
}
public Menu()
{
InitializeComponent();
LockKeys();
}
This is now the menu code which assigns the int to a class variable.
I've got 10 different reports and when I hit the back key on a report, this is how i call the menu back.
Menu shwMenu = new Menu();
shwMenu.Show();
this.Hide();
Now I understand the problem is that its calling the constructor that doesn't assign the variable. Right now all i can think of doing is bouncing the variable to each report and back, simply to call the correct constructor.
My question is, is there an easier way to do it ? some way to save the class variable so I don't have to re-instantiate it every time the class is called.
public partial class Menu : Form
{
private int AccessLevel;
public Menu(string Permission)
{
InitializeComponent();
AccessLevel = int.Parse(Permission);
LockKeys();
}
public Menu()
{
InitializeComponent();
LockKeys();
}
private void LockKeys()
{
if(AccessLevel == 1)
{
btnSR.Enabled = false;
btnVSC.Enabled = false;
btnPT.Enabled = false;
btnCT.Enabled = false;
btnTS.Enabled = false;
btnBookJob.Enabled = false;
btnCompJob.Enabled = false;
btnCompServ.Enabled = false;
btnVS.Enabled = true;
}
else if (AccessLevel == 2)
{
btnSR.Enabled = false;
btnVSC.Enabled = false;
btnPT.Enabled = false;
btnCT.Enabled = false;
btnTS.Enabled = false;
btnBookJob.Enabled = true;
btnCompJob.Enabled = true;
btnCompServ.Enabled = false;
btnVS.Enabled = false;
}
else if (AccessLevel == 3)
{
btnSR.Enabled = false;
btnVSC.Enabled = false;
btnPT.Enabled = false;
btnCT.Enabled = false;
btnTS.Enabled = false;
btnBookJob.Enabled = true;
btnCompJob.Enabled = false;
btnCompServ.Enabled = true;
btnVS.Enabled = false;
}
else if (AccessLevel == 4)
{
btnSR.Enabled = false;
btnVSC.Enabled = false;
btnPT.Enabled = false;
btnCT.Enabled = false;
btnTS.Enabled = true;
btnBookJob.Enabled = false;
btnCompJob.Enabled = false;
btnCompServ.Enabled = false;
btnVS.Enabled = false;
}
}
private void btnVS_Click(object sender, EventArgs e)
{
VehicleStatR1 VS = new VehicleStatR1();
VS.Show();
this.Hide();
}
private void btnSR_Click(object sender, EventArgs e)
{
ServRequireR3 SR = new ServRequireR3();
SR.Show();
this.Hide();
}
private void btnVSC_Click(object sender, EventArgs e)
{
VehServCompleteR4 VSC = new VehServCompleteR4();
VSC.Show();
this.Hide();
}
private void btnPT_Click(object sender, EventArgs e)
{
PlannedTripR6 PT = new PlannedTripR6();
PT.Show();
this.Hide();
}
private void btnCT_Click(object sender, EventArgs e)
{
ActualTripR7 CT = new ActualTripR7();
CT.Show();
this.Hide();
}
private void btnTS_Click(object sender, EventArgs e)
{
HoursWorkedR8 TS = new HoursWorkedR8();
TS.Show();
this.Hide();
}
private void btnBookJob_Click(object sender, EventArgs e)
{
BookJobServ BJ = new BookJobServ();
BJ.Show();
this.Hide();
}
private void btnCompJob_Click(object sender, EventArgs e)
{
CompJob CJ = new CompJob();
CJ.Show();
this.Hide();
}
private void btnCompServ_Click(object sender, EventArgs e)
{
CompServ CS = new CompServ();
CS.Show();
this.Hide();
}
private void btnLogOut_Click(object sender, EventArgs e)
{
LogIn LI = new LogIn();
this.Hide();
LI.Show();
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
This is the menu class, the one i keep backtracking to but the AccessLevel variable changes to the default value.
Thanks

I think what you are looking for is a "static" variable which is a class level variable.
private static int AccessLevel;
Static variables are defined in a class level and all instances of the class can access them and modify them. In other words, static variables are shared between class instances. more information: https://msdn.microsoft.com/en-us/library/98f28cdx.aspx?f=255&MSPPError=-2147217396

Another option would be to use a static class that holds all the information you need, for example:
public static class CurrentUser
{
public static string UserName { get; set; }
public static int AccessLevel { get; set; }
}
Which you use when your user logs in:
public void LogUserIn(string userName, string password)
{
//Make sure to reset, so an invalid login doesn't retain data
LogUserOut();
//Do the user validation here
CurrentUser.UserName = userName;
CurrentUser.AccessLevel = 0; //whatever was read from your user database
}
public void LogUserOut()
{
CurrentUser.UserName = "";
CurrentUser.AccessLevel = int.MinValue;
}
And then, when you need to use the access level you don't need to worry about passing values around, for example your Menu form would look like this:
public partial class Menu : Form
{
public Menu()
{
InitializeComponent();
LockKeys();
}
private void LockKeys()
{
if(CurrentUser.AccessLevel == 1)
{
//Enable/Disable Controls
}
else if (CurrentUser.AccessLevel == 2)
{
//Enable/Disable Controls
}
else if (CurrentUser.AccessLevel == 3)
{
//Enable/Disable Controls
}
else if (CurrentUser.AccessLevel == 4)
{
//Enable/Disable Controls
}
}
}
As a side note, in order to avoid code duplication and to increase security, you should create your initialization function LockKeys like this:
private void LockKeys()
{
//Set them all default false, and then only enable.
btnSR.Enabled = false;
btnVSC.Enabled = false;
btnPT.Enabled = false;
btnCT.Enabled = false;
btnTS.Enabled = false;
btnBookJob.Enabled = false;
btnCompJob.Enabled = false;
btnCompServ.Enabled = false;
btnVS.Enabled = false;
if(AccessLevel == 1)
{
btnVS.Enabled = true;
}
else if (AccessLevel == 2)
{
btnBookJob.Enabled = true;
btnCompJob.Enabled = true;
}
else if (AccessLevel == 3)
{
btnBookJob.Enabled = true;
btnCompServ.Enabled = true;
}
else if (AccessLevel == 4)
{
btnTS.Enabled = true;
}
}

Related

Timer check Winform topmost enabled

how i can make a loop timer that check if in main form topmost.enable is false until a label is visible and then set to true when the label deactive?
If tried this code but not work:
private void InitializeAlive()
{
alive = new System.Timers.Timer();
alive.Interval = 1000;
alive.AutoReset = true;
alive.Elapsed += Alive_Tick;
alive.Start();
}
private void Alive_Tick(object sender, EventArgs e)
{
if (lblPassword.Enabled)
{
this.TopMost = false;
}
else
{
this.TopMost = true;
alive.Dispose();
}
}
private void btnPrint_Click(object sender, EventArgs e)
{
if (txtPassword.Text == pswd)
{
TopMost = false;
webPrintSetting.ShowPageSetupDialog();
InitializeAlive();
}
else
{
btnPrint.Enabled = false;
btnPrint.Visible = false;
lblPassword.Visible = false;
txtPassword.Enabled = false;
txtPassword.Visible = false;
txtPassword.Clear();
}
}
If you only need to do something when 'Enabled' property of the label changes, then you can simply add handler to the 'EnabledChanged' property, like this:
public Form1()
{
InitializeComponent();
lblPassword.EnabledChanged += new System.EventHandler(this.LblPassword_EnabledChanged);
}
And implement the handler like this:
private void LblPassword_EnabledChanged(object sender, EventArgs e)
{
TopMost = !lblPassword.Enabled;
}
I find a solution to toggle on/off topmost (off until a target process is running).
private Timer check;
public MyForm()
{
InitializeCheck();
}
private void InitializeCheck()
{
check = new Timer();
check.Interval = 5000;
check.Tick += Check_Tick;
check.Enabled = false;
}
private void Check_Tick(object sender, EventArgs e)
{
CheckProgram();
}
private void CheckProgram()
{
Process[] program = rocess.GetProcessesByName("notepad");
if (program.Length == 0)
{
check.Enabled = false;
TopMost = true;
}
private void button1_Click(object sender, EventArgs e)
{
TopMost = false;
check.Enabled = true;
}

How can I manipulate 4 Panel in one form?

I have 4 panels each of one has their own TextBoxes, Buttons, and DataGridView. My problem is only two panels are showing the other is none. When I click the 1st Button I want to show the panel1 and hide the other panels. And when I click the 2nd Button I want to hide the panel1 and the other panel. How can I do it? Can somebody help me with my problem? It this possible to happen?
private void btnItems_Click(object sender, EventArgs e)
{
if (pnlItems.Visible != true)
{
pnlItems.Visible = true;
pnlCustomer.Visible = false;
pnlPOS.Visible = false;
pnlDelivery.Visible = false;
}
}
private void btnCustomers_Click(object sender, EventArgs e)
{
if (pnlCustomer.Visible != true)
{
pnlCustomer.Visible = true;
pnlItems.Visible = false;
pnlPOS.Visible = false;
pnlDelivery.Visible = false;
}
}
private void btnPOS_Click(object sender, EventArgs e)
{
if (pnlPOS.Visible != true)
{
pnlPOS.Visible = true;
pnlCustomer.Visible = false;
pnlItems.Visible = false;
}
}
private void btnDelivery_Click(object sender, EventArgs e)
{
if (pnlDelivery.Visible != true)
{
pnlDelivery.Visible = true;
pnlPOS.Visible = false;
pnlCustomer.Visible = false;
pnlItems.Visible = false;
}
}
private void frmMain_Load(object sender, EventArgs e)
{
pnlItems.Visible = true;
pnlCustomer.Visible = false;
pnlPOS.Visible = false;
pnlDelivery.Visible = false;
}
Let's extract a method:
private void MakePanelVisisble(Panel panel) {
Panel[] panels = new Panel[] {
pnlItems, pnlCustomer, pnlPOS, pnlDelivery,
};
foreach (var p in panels)
p.Visible = (p == panel);
}
Then
private void btnItems_Click(object sender, EventArgs e) {
MakePanelVisisble(pnlItems);
}
private void btnCustomers_Click(object sender, EventArgs e) {
MakePanelVisisble(pnlCustomer);
}
...
private void frmMain_Load(object sender, EventArgs e) {
MakePanelVisisble(pnlItems);
}
Just Give your Panels Tags 1,2,3,4;
the write a method like this:
private void ShowPanel(int id)
{
var panels = myform.Controls.OfType<Panel>();
foreach(Panel p in panels)
p.Visible = (int)p.Tag == id)
}
Then in your buttons use it like:
private void btnPOS_Click(object sender, EventArgs e)
{
ShowPanel(2);
}

Sending Data Between Two Forms C#

Click to see problem explain by Image i have two form ...
on form1 there is a submit button which when pressed form2 should be open with username textbox and submit button ....
when user press submit button form1 will be appeared again and button text will be change to username and new sign up button will appear ....
it works for first press but on second button press first button text goes to default text , how to fix this ?
class 1
namespace Internship_Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string b;
public Form1(Form2 obj)
{
InitializeComponent();
if(button1.Name == obj.b2)
{
button1.Text = obj.username;
button2.Visible = true;
}
else if(button2.Name == obj.b2)
{
button2.Visible = true;
button2.Text = obj.username;
button3.Visible = true;
}
else if (button3.Name == obj.b2)
{
button2.Visible = true;
button3.Visible = true;
button3.Text = obj.username;
button4.Visible = true;
}
else if (button4.Name == obj.b2)
{
button2.Visible = true;
button3.Visible = true;
button4.Visible = true;
button4.Text = obj.username;
button5.Visible = true;
}
else if (button4.Name == obj.b2)
{
button2.Visible = true;
button3.Visible = true;
button4.Visible = true;
button5.Visible = true;
button5.Text = obj.username;
}
}
private void button1_Click(object sender, EventArgs e)
{
this.b = ((Button)sender).Name;
Form2 obj = new Form2(this);
obj.ShowDialog();
this.Hide();
}
}
}
class 2
namespace Internship_Test
{
public partial class Form2 : Form
{
string[] user = new string[5];
public Form2()
{
InitializeComponent();
}
public string b2;
public Form2(Form1 obj)
{
InitializeComponent();
b2 = obj.b;
}
public string username;
private void button1_Click(object sender, EventArgs e)
{
username = textBox2.Text;
Form1 obj = new Form1(this);
obj.Show();
this.Hide();
}
}
}[Click to see problem explain by Image ][1]
As response on your question/bug, like Mong Zhu pointed out:
Your bug is found here:
class 2
namespace Internship_Test
{
public partial class Form2 : Form
{
string[] user = new string[5];
public Form2()
{
InitializeComponent();
}
public string b2;
private Form1 _form1; // you need to create a field for the form1
public Form2(Form1 form1)
{
InitializeComponent();
b2 = obj.b;
_form1 = form1;
}
public string username;
private void button1_Click(object sender, EventArgs e)
{
username = textBox2.Text;
//Form1 obj = new Form1(this);
// instead of creating a new form, just pop it up:
_form1?.Show();
this.Hide();
}
}
}
And you should change the obj.ShowDialog(); to obj.Show();
Some questions:
Why would you hide the form1?
Why are you pass an instance of Form2 into the constructor of Form1?
I would implement it like:
public class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
using(var form2 = new Form2())
{
// if you want to fill the username before popup..
// do it here:
// form2.UserName = textBox2.Text;
var result = form2.ShowDialog();
if(result != DialogResult.OK)
return;
textBox2.Text = form2.UserName;
}
}
}
public class Form2 : Form
{
public string UserName
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
}

How to solve memory leak in window form

My problem is that memory is increased 5MB flicker form each time a call per second .
I made window flicker effect window form
[flicker form]
public partial class WarningBoxControls : Form
{
bool _isShadow;
public WarningBoxControls(WarningBoxType _Type)
{
InitializeComponent();
this.FormClosing += WarningBox_FormClosing;
this.VisibleChanged +=WarningBoxControls_VisibleChanged;
if (_Type == WarningBoxType.WarningBox_Speed)
{
MessageTitle.Text = "속력 경고";
MessageContent.Text = "자동차 속도를 줄여주세요!";
this.BackColor = Color.SkyBlue;
pictureBox1.Image = Properties.Resources.warning_speed;
}
else
{
MessageTitle.Text = "Logger 오류";
MessageContent.Text = "Logger가 활성화되지 않았습니다!";
this.BackColor = Color.MediumVioletRed;
pictureBox1.Image = Properties.Resources.warning_error;
}
}
private void WarningBoxControls_VisibleChanged(object sender, EventArgs e)
{
this.Opacity = 0.01;
if(this.Visible == true)
{
timer1.Start();
}
else
{
timer1.Stop();
}
}
private void WarningBox_FormClosing(object sender, FormClosingEventArgs e)
{
if (pictureBox1.Image != null)
{
pictureBox1.Image = null;
pictureBox1.Dispose();
}
if (timer1.Enabled == true)
{
timer1.Stop();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (_isShadow == false)
{
if (this.Opacity <= 1.0)
{
this.Opacity += 0.8;
if (this.Opacity >= 1.0)
{
_isShadow = true;
}
}
}
else
{
if (this.Opacity >= 0.01)
{
this.Opacity -= 0.08;
if (this.Opacity <= 0.01)
{
_isShadow = false;
}
}
}
}
}
And I created the class to load flicker effect form.
[load ficker form]
public class WarningBox
{
WarningBoxControls _control;
Form owner;
public WarningBox(IWin32Window _owner, WarningBoxType _Type)
{
if (_owner != null)
{
owner = (Form)_owner;
_control = new WarningBoxControls(_Type);
_control.StartPosition = FormStartPosition.Manual;
_control.Padding = new Padding(0, 0, 0, 0);
_control.ControlBox = false;
_control.ShowInTaskbar = false;
_control.Size = new Size(owner.Size.Width - 40, _control.Height - 20);
}
}
public void Show()
{
_control.Location = new Point(owner.Location.X + 20, owner.Location.Y + ((owner.Height - _control.Height) / 2));
//_control.ShowDialog();
//_control.BringToFront();
if(_control.Visible != true)
{
_control.Show();
_control.BringToFront();
}
}
public void Hide()
{
if(_control.Visible != false)
{
//_control.Visible = false;
_control.Hide();
}
}
~WarningBox()
{
if(_control != null)
{
_control.Dispose();
_control = null;
}
}
}
[Call a second method]
private void timer1_Tick(object sender, EventArgs e)
{
if (NetworkInterface.GetIsNetworkAvailable())
{
ReadLoggerStatus();
}
private void ReadLoggerStatus()
{
if (_Lights != null)
{
if (_Lights.ERR == 0) // 에러 없을때
{
pb_error.Image = Properties.Resources.none;
_WarningBox.Hide();
btn_stop.Enabled = true;
btn_start.Enabled = false;
}
else
{
pb_error.Image = Properties.Resources.error;
_WarningBox.Show();
btn_stop.Enabled = false;
btn_start.Enabled = true;
}
}
}
And Check the one error per second , call the Show() and Hide() of WarningBox. however here(ReadLoggerStatus()) is some of a problem.
my problem is that the memory each time it is called once per second increased by 5MB.
I want to know it is solve the best way.
please let me know excellent answer.
In advance, I would greetings of thanks.
Have a good day!

How to prevent firing CheckedChanged event when checking a control programmatically?

How do I prevent firing CheckedChanged event when checking a control programmatically?
I usually do this the following way.
private bool isFrozen = false;
private void btn1_CheckedChanged(object sender, EventArgs e)
{
if (isFrozen)
return;
isFrozen = true;
btn2.Checked = false;
isFrozen = false;
// Do some stuff
}
private void btn2_CheckedChanged(object sender, EventArgs e)
{
if (isFrozen)
return;
isFrozen = true;
btn1.Checked = false;
isFrozen = false;
// Do another stuff
}
Is there a better or more common solution?
I think your way is fine.
The other way to do it is remove the EventHandler before the check, and then add it back again after the check. This way eliminates the need for the isFrozen variable.
private void btn1_CheckedChanged(object sender, EventArgs e)
{
btn2.CheckedChanged -= btn2_CheckedChanged;
btn2.Checked = false;
btn2.CheckedChanged += btn2_CheckedChanged;
// Do some staff
}
private void btn2_CheckedChanged(object sender, EventArgs e)
{
btn1.CheckedChanged -= btn1_CheckedChanged;
btn1.Checked = false;
btn1.CheckedChanged += btn1_CheckedChanged;
// Do another staff
}
In VB:
RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
I came across this post after wanting to implement something like this for a while. I regularly use Measurement Studio from National Instruments, and their WinForms controls that have the event StateChanging or StateChanged pass a parameter of type ActionEventArgs, which has a property Action which can take three values: ByKeyboard, ByMouse and Programatic. This is very useful in determining what has caused the state of the control to change. I wanted to replicate this in a standard WinForms checkbox.
Here is my code:
public enum ControlSource
{
Programatic,
ByKeyboard,
ByMouse
}
public class AwareCheckBox : Checkbox
{
public AwareCheckBox()
: base()
{
this.MouseDown += AwareCheckbox_MouseDown;
this.KeyDown += AwareCheckbox_KeyDown;
}
private ControlSource controlSource = ControlSource.Programatic;
void AwareCheckbox_KeyDown(object sender, KeyEventArgs e)
{
controlSource = ControlSource.ByKeyboard;
}
void AwareCheckbox_MouseDown(object sender, MouseEventArgs e)
{
controlSource = ControlSource.ByMouse;
}
public new event AwareControlEventHandler CheckedChanged;
protected override void OnCheckedChanged(EventArgs e)
{
var handler = CheckedChanged;
if (handler != null)
handler(this, new AwareControlEventArgs(controlSource));
controlSource = ControlSource.Programatic;
}
}
public delegate void AwareControlEventHandler(object source, AwareControlEventArgs e);
public class AwareControlEventArgs : EventArgs
{
public ControlSource Source { get; private set; }
public AwareControlEventArgs(ControlSource s)
{
Source = s;
}
}
I'm sure there are improvements to make, but my rudimentary testing has demonstrated that it works. I have posted here simply in case others stumble across this issue and want a clearer way of distinguishing where the change was initiated. Any comments welcome.
Just have a counter value set and check for the value in the beginning of the event. It solved my problem in 10 minutes. I am using 5 slide buttons in Xamarin to make it as a radio button.
private void testtoggle1(object sender, ToggledEventArgs e)
{
if (chk_ctr == 1) { return; }
chk_ctr = 1;
sw2.IsToggled= false;
sw3.IsToggled = false;
sw4.IsToggled = false;
sw5.IsToggled = false;
chk_ctr = 0;
}
private void testtoggle2(object sender, ToggledEventArgs e)
{
if (chk_ctr == 1) { return; }
chk_ctr = 1;
sw1.IsToggled = false;
sw3.IsToggled = false;
sw4.IsToggled = false;
sw5.IsToggled = false;
chk_ctr = 0;
}
private void testtoggle3(object sender, ToggledEventArgs e)
{
if (chk_ctr == 1) { return; }
chk_ctr = 1;
sw1.IsToggled = false;
sw2.IsToggled = false;
sw4.IsToggled = false;
sw5.IsToggled = false;
chk_ctr = 0;
}
private void testtoggle4(object sender, ToggledEventArgs e)
{
if (chk_ctr == 1) { return; }
chk_ctr = 1;
sw1.IsToggled = false;
sw2.IsToggled = false;
sw3.IsToggled = false;
sw5.IsToggled = false;
chk_ctr = 0;
}
private void testtoggle5(object sender, ToggledEventArgs e)
{
if (chk_ctr == 1) { return; }
chk_ctr = 1;
sw1.IsToggled = false;
sw2.IsToggled = false;
sw3.IsToggled = false;
sw4.IsToggled = false;
chk_ctr = 0;
}

Categories