Call Paint event handler from Timer to update form controls [duplicate] - c#

This question already has answers here:
How do I call paint event?
(8 answers)
Why did I get the compile error "Use of unassigned local variable"?
(10 answers)
Closed 1 year ago.
I am trying to create a method for a timer event that takes 3 arguments. I have had a look at similar questions and tried to implement the solutions shown but the solution do not work in my case
GraphDrawingTimer.Elapsed += new ElapsedEventHandler(GraphPainter);
GraphDrawingTimer.Interval = 350;
GraphDrawingTimer.Enabled = true;
Above is the timer initialization
static void GraphPainter(object sender, ElapsedEventArgs e)
{
//Show_Graph(c);
}
thats method that will be called once the timer fires.
I want to add a PaintEventArgs c extra argument to draw a graph. I was using
private void tabPage2_Paint(object sender, PaintEventArgs e)
method but buttons do not get refreshed on my tabpage, thats why I want to create my own graph drawing method that will refresh every 350 milli-second.
I have tried
GraphDrawingTimer.Elapsed += (object sender, ElapsedEventArgs e) => { GraphPainter(sender, e, c); };
GraphDrawingTimer.Interval = 350;
GraphDrawingTimer.Enabled = true;
.....
static void GraphPainter(object sender, ElapsedEventArgs e, PaintEventArgs c)
{
Show_Graph(c);
}
but that does not work. I get the error "The name 'c' does not exist in the current context".
I also tried
PaintEventArgs c;
GraphDrawingTimer.Elapsed += (object sender, ElapsedEventArgs e)=> { GraphPainter(sender, e, c); };
GraphDrawingTimer.Interval = 350;
GraphDrawingTimer.Enabled = true;
.....
static void GraphPainter(object sender, ElapsedEventArgs e, PaintEventArgs c)
{
Show_Graph(c);
}
I get the following error
Error CS0165 Use of unassigned local variable 'c'
Which indeed makes sense since I'm not assigning any value to it - so how to assign a value to that PaintEventArgs c to pass correct parameter of the Paint event? Or maybe there should be some other approach to invoke Paint event?

PaintEventArgs might not be valid that way. The best option is to use the .Invalidate() method on the controls you want to update from your timer and that will cause their paint events to be called.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.invalidate?view=net-5.0
This might look something like:
GraphDrawingTimer.Elapsed +=
(object sender, ElapsedEventArgs e) => MyGraphControl.Invalidate();

Related

How to call common Method to multiple Events

Hello I have this code:
private void txtNumero_KeyDown(object sender, KeyEventArgs e)
{
CercaCliente();
}
private void txtNote_KeyDown(object sender, KeyEventArgs e)
{
CercaCliente();
}
private void txtNominativo_KeyDown(object sender, KeyEventArgs e)
{
CercaCliente();
}
How can I write this code in better mode? Thanks
there are two approaches you can choose from, and it depends what type of effort you are ready to do...
first when you bind the event there itself call the method rather than creating handler method for each.
Currently, you are doing -
txtNumero.KeyDown += new txtNumero_KeyDown;
..
..
txtNote.KeyDown += new txtNumero_KeyDown;
then in your method you are calling this common method 'CercaCliente()'. you can directly use func delegate to call you common method. e.g.
txtNumero.KeyDown += (o,e)=>CercaCliente();
..
..
txtNote.KeyDown += (o, e)=>CercaCliente();
OR
You can create custom control, derived from textbox, and there you can handle it.
Add this common method
private void HandlerMethod(object sender, EventArgs e)
{
CercaCliente();
}
Then inside your form load Attach this handler method to all events
this.txtNominativo.KeyDown += HandlerMethod;
this.txtNote.KeyDown += HandlerMethod;
this.txtNumero.KeyDown += HandlerMethod;

Action when Form is closed c#

I'm in College and this is my first (major) project.
I'm trying to perform an action when a form is closed. I don't seem to be getting the terminology right when searching online, or the answer given doesn't match what I want to do.
At the moment i'm declaring a Class and displaying the from -
private void createuser_Click(object sender, EventArgs e)
{
User_Modification mod = new User_Modification("Create", "Create");
mod.ShowDialog();
}
What I want to do is this -
WHEN mod IS CLOSED {
// Do stuff
}
You're using ShowDialog, so the code following it is not executed until after the dialog box is closed. mod.ShowDialog(); doStuff(); will work pretty well.
You need to create a handler to capture the FormClosed event:
In your constructor do:
this.FormClosed += Form_Closed;
Then in the body of your form, add this method.
private void Form_Closed(object sender, FormClosedEventArgs e)
{
// Do stuff
}
You should attach handler to FormClosed event:
private void createuser_Click(object sender, EventArgs e)
{
User_Modification mod = new User_Modification("Create", "Create");
mod.FormClosed += new FormClosedEventHandler(FormClosed);
mod.ShowDialog();
}
void FormClosed(object sender, FormClosedEventArgs e)
{
MessageBox.Show("Closed");
}
if you're using WinForms you can override OnFormClosing event:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
// your code...
}
You'll want to take a look at two events:
Form.FormClosing : https://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing(v=vs.110).aspx
Form.FormClosed : https://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosed%28v=vs.110%29.aspx
First one will allow you to perform actions prior to the form being closed completely, such as canceling the closing procedure. The second one is what you would use if you want to perform actions after the form is closed (perhaps to clean up resources, as an example).
So, as an example, let's say that you want to perform an action when the form is in fact closed:
// Somewhere in your code where you create the form object.
form.FormClosed += Form_FormClosed;
// Somewhere else in your code.
private void Form_FormClosed(Object sender, FormClosedEventArgs e)
{
MessageBox.Show("Form closed");
}

Different objects calling same method, how can I set the "caller's" property?

I have 15 images on my WPF application. I want it so that whenever MouseUp on any of the images is called.. it'll call the same method.
I would like to do something similar to the psuedo code written here.. This would save so much time instead of writing 15 individual methods for each button. How can I do something like this?
private void BluePick1_Image_MouseUp_1(object sender, MouseButtonEventArgs e)
{
sender.ImageSource = something;
}
thank you for any help
if your event is always on a button :
private void ButtonMouseUp(object sender, MouseButtonEventArgs e) {
((Button)sender).ImageSource = something;
}
and
button1.MouseUp += ButtonMouseUp;
button2.MouseUp += ButtonMouseUp;

Auto refresh labels as text boxes text input data into method

Here is my method that I' am trying to have automatically refresh my label. When I have my label as a click event...the answer refreshes and is correct.
private void Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
}
Here is the Validated label event that does not update when text is changed in my text boxes.
private void lblUtil1_Validated(object sender, EventArgs e)
{
Calculate();
}
If this is correct...what am I missing? is there something I need to do on the text boxes that will trigger validation?
I have also tried a text changed event that yields the error cannot implicitly convert type void(or any type for that matter) to EventHandler. Here is the code.
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged += Calculate();
}
Any help is appreciated! I've been banging my head on my keyboard for a day now.
First at all, you have to handle events for the TextBox that you input value to calculate, such as when you change vale in the TextBox or validate it.
So if you have textBox1 then you should have this handling (trigger when value in textBox1 is changed)
private void textBox1_TextChanged(object sender, EventArgs e)
{
lblUtil1.Text = Calculate();
}
I assume that you want to display value in strUtil1 at the label lblUtil1, so you have to change your Calculate method like this
private string Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
return strUtil1;
}
EDITED
This is a sample code for validate the required TextBoxes.
private void textBox1_Validating(object sender, CancelEventArgs e)
{
if (textBox1.Text == "")
{
e.Cancel = true;
lblUtil1.Text = "textBox1 is required!";
}
}
Try calling yourlabelname.Refresh() i.e like
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged = Calculate();
lblUtil1.Refresh();
}
or
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
Calculate();
lblUtil1.Refresh();
}
You need to do a couple things.
First, stop using "hungarian" notation. It's bad. It's bad for a lot of reasons. MS even says, "don't use hungarian" as most people get it wrong as your code shows. Instead, name your variables appropriately. For example, dblSG has absolutely zero meaning.
Second, please reread Michael's answer to your question from yesterday ( https://stackoverflow.com/a/20026642/2424 ). He did NOT say to use lblUtil1_Validated. He said to use TextBox_Validated. In other words, the event you should have your calculation run on is with the textbox fields on your form. He also suggested you just use the textboxes TextChanged events in order to cause the calculation to run as they are typing. Personally, I don't agree with that but whatever.
A third possible option is to simply go back to your original solution. Meaning, just run the calculation when the label is clicked. In which case you should refer back to your original question as Michael failed to answer it.

Timers in C#, how to control whats being sent to the timer1_tick

In this following function, that gets executed whenever I do
timer1.Enabled = true
private void timer1_Tick(object sender, EventArgs e)
{
//code here
}
How can I control what gets send to the (object sender, EventArgs e) ?
I want to use its parameters
The method signature is fixed, so you can't pass extra parameters to it. However, the this reference is valid within the event handler, so you can access instance members of the class (variables declared inside class but outside of any method).
1) You can use Tag property of your timer as userState
void timer1_Tick(object sender, EventArgs e)
{
Timer timer = (Timer)sender;
MyState state = timer.Tag as MyState;
int x = state.Value;
}
2) You can use field of reference type to read it in Timer's thread
void timer1_Tick(object sender, EventArgs e)
{
int x = _myState.Value;
}
3) You can use System.Threading.Timer to pass state to timer event handler
Timer timer = new Timer(Callback, state, 0, 1000);
If you want to access Timer's property in the timer1_tick method, you could do via
this.timer1 ex: this.timer1.Enabled =false;
or
Timer timer = (Timer) sender;
timer.Enabled = false;
Maybe you could make an inheritance from timer class, and there, cast the tick event (from Timer) into a tick_user event or something like this that modify de params and put into EventArgs (this is the right place to do, not in sender) other parameters you want. Also you can make a method with more or less parameters, it's up to you.
Hope this helps.

Categories