I have the following problem with System.Windows.Forms (C#):
I have a CheckBox in my program and I defined an event handler for CheckedChanged. The problem is that when the user clicks the CheckBox, it may happen that it takes several seconds until the CheckBox is visibly marked as checked.
I set a breakpoint inside the CheckedChanged event and noticed that indeed, it sometimes takes several seconds until the CheckedChanged event fires. How can it be that the CheckedChanged event lags behind that much?
Unfortunately I have not been able to find information in the literature regarding the matter when exactly the CheckedChanged event is triggered. Might it be that another event is handled first before the CheckedChanged event is triggered, so I could catch this event instead and make the check-arrow appear in time?
Thank you for your help and suggestions.
The CheckedChanged event occurs when the Checked property of the CheckBox changes.
The UI will not update the checkmark inside the checkbox, until after any eventhandler for this event has been handled. If you are doing a lot of processing in the handler for the CheckedChanged event, then it will take some time before the checkmark is added/removed from the checkbox.
If you need the UI to update quickly, then consider doing the processing in a separate thread. This can be done pretty easily, using Task.
Here's a quick example:
private void MyCheckBox_CheckedChanged(object sender, EventArgs e)
{
//Don't do this:
//ThreeSecondMethod();
//Instead, do this:
Task.Run(() => ThreeSecondMethod());
}
private void ThreeSecondMethod()
{
DateTime deadline = DateTime.Now.AddSeconds(3);
while(DateTime.Now < deadline)
{
/* Do nothing */
}
MessageBox.Show("Done!");
}
Related
Is it possible to know if any of the textbox values have changed in the application.
I have around 30 textboxes and I want to run a part of code only if, any of the textboxes value has changed out of the 30. Is there a way I can know that.
Each text box will raise an event TextChanged when it's contents have changed. However, that requires you to subscribe to each and every event.
The good news is that you can subscribe to the event with the same method multiple times. The handler has a parameter sender which you can use to determine which of your 30 text boxes has actually raised the event.
You can also use the GotFocus and LostFocus events to keep track of actual changes. You would need to store the original value on GotFocus and then compare to the current value on LostFocus. This gets round the problem of two TextChanged events cancelling each other out.
You can assign an event handler to each of the TextBox's TextChanged events. All of them can be assigned to the same event handler in code. Then you'll know when the text changes. You can set a boolean flag field in your class to record that a change occurred.
This is perhaps on the rough and ready side, but I did it this way.
In the constructor, I created
bool bChanged = false;
In the TextChanged event handler of each control (actually same for each), I put
bChanged = true;
When appropriate, I could do some processing, and set bChanged back to false.
You can also just do this:
In your Constructor:
MyTextBox.TextChanged += new TextChangedEventHandler( TextChanged );
And Then this Method:
private void TextChanged(object Sender, TextChangedEventArgs e){
//Do something
}
try this. Add this code to the load/constructor. no need to specify the event in the XAML explicitly
this.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextChanged));
private void TextChanged(object Sender, TextChangedEventArgs e)
{
//ToDO (use sender to identify the actuale text from where it fired }
}
Hello i basically added datagridviews dynamically to my windows form application, and added cellClick event handlers dynamically by looping through all the datagridview control, however my event doesnt fire consistently, like when i click really fast it wont clear the selection sometimes. here is my code
void DGV_CellClick(Object sender, EventArgs e)
{
DataGridView dgv = (DataGridView)sender;
dgv.ClearSelection();
}
foreach(KeyValuePair<int,datagridview>entry in DGVCollection)
{
datagridview dgv = entry.value;
dgv.CellClick+= DGV_CellClick;
}
"however my event doesnt fire consistently, like when i click really fast it wont clear the selection sometimes. here is my code"
It's possible that the CellDoubleClick event get's fired instead of the CellClick event.
You could take a look at this link
Is there an event for panel that is equivalent to form event Shown?
I had a few couple of panel switching within a form which will never be closed.
However i couldn't find anything close to an event like Shown which is used in form.
The closes i had is Paint event. However i only wish to update the panel once every time it is shown.
Form.Shown is not raised every time the form is shown, rather it Occurs whenever the form is first displayed. This being said, there is no Panel.Shown event, and no event which is raised "whenever a panel is first displayed".
You can simulate this behavior with the Panel.Paint event, using a flag to keep track of whether it's been "shown" once before. This will make it behave similar to Form.Shown.
private bool panel1Painted = false;
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (!panel1Painted)
{
// do your shown stuff here
panel1Painted = true;
}
}
To keep in the spirit of Form.Shown, you may want to reset the flag if the Panel is reconstructed. This is not the same as shown.
You could listen on the VisibleChanged event and only act on when visibility = true.
https://msdn.microsoft.com/en-us/library/system.windows.forms.panel_events%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
You could also experiment with the Enter and Invalidated events to see if these give you the results you want.
Or if disabling the panel when leaving it is an option, you might be able to use the EnabledChanged event in your toolbox.
I have made my own Button User control in a WPF application.
In this, I'm trying to raise a event attached with multiple event handlers on another event.
I have multiple event handlers attached with "MouseUp" Event for View and business logic (MVVM). I just want to fire all the handlers attached with "MouseUp" event On "KeyUp" with "Enter" and "SpaceBar"
Here is the sample code which I used to raise "MouseUp" event on "KeyUp" if the key is enter or space
void Button_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space || e.Key == Key.Enter)
{
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
RoutedEvent = Mouse.MouseUpEvent,
Source = this,
});
}
}
Not sure. I may be wrong. But it worked for me. However, not in all case.
In some of the cases, the event not raising as expected.
In my further investigation, Im seeing the key up event get triggered. But the none of the event handlers in "MouseUp" event raised in some objects.
Is there any elegant way to achieve my need.
This breaks the expected pattern for anyone reading the code - why would the mouseup event need to be fired when the key is released? If it's just to avoid code duplication, you should have a separate method which both the mouseup and the keyup call.
As per the comments, if you have multiple event handlers attached, you will need to attach all of them to both events. Alternatively, you could create a meta-event-handler that calls all the others as methods, then just attach that one to each event.
Just create function and work with events separately, adding reference to this function as events handler.
had the issue that my KeyUp and the KeyDown Event both fired twice when i invoked them. Finally found a fix for this:
this.glControl1.KeyUp -= this.glControl1_KeyUp;
this.glControl1.KeyUp += new KeyEventHandler(this.glControl1_KeyUp);
It works, but i really cant understand why. Could anyone explain me please.
Thank you
You probably have some repetitive event which you use as a trigger to hook up your event handler, a classic example is a button click e.g.
public void ButtonClick(object sender, EventArgs e)
{
this.SomeControl.KeyUp += this.SomeHandler;
}
The problem here is everytime the button is clicked the same event handler is assigned to the same event, there is nothing to prevent this from happening as it can be perfectly acceptable under certain circumstances.
To avoid this, you need to unhook the event handler before you reassign it, this is why executing the following line of code
this.SomeControl.KeyUp -= this.SomeHandler;
Before you assign the event handler prevents duplicate calls.