KeyUp - triggering twice - c#

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.

Related

C# Windows Forms CheckedChanged lags behind

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!");
}

Raise Event on When a different event raised - C#

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.

How to cancel an event without using e.Cancel method?

I want to cancel the Data gridview cell click event
private void gridViewHistory_CellClick(object sender, DataGridViewCellEventArgs e)
{
}
but this eventargs doesn't have cancel event, How to cancel that event ?
May be this question has a very easy answer but still i am stuck it in, needs help.
Thanks in advance.
You can't.
WinForms events are just multicast delegates then they can't be canceled (in the sense of stop propagation of the event) unless this situation is handled by the object that exposes the event (but I'm now aware of any object that supports this, usually events are notifications).
That said, some events has argument with a Cancel property, it's used by the object to cancel the action that should be performed because of that event. Again if the implementation does not provide that property there is not anything you can do to change this behavior.
In your case you should override the OnCellClick method of DataGridView to handle that in the way you prefer (if you do not call the base class then cell won't get the click event and CellClick event won't be fired).
Not all events can be cancelled. You can choose to not do anything in your event handler but that doesn't mean you can cancel it.
So, unless there is a specific Cancel type method you Cannot cancel the event.
You may want to use CellValidating event:
private void gridViewHistory_CellValidating(object sender,
DataGridViewCellValidatingEventArgs e)
{
if (.....)
{
e.Cancel = true;
}
}
You can try the
return;
statement, but this only works for asp:LinkButton OnClick events that do not then pass over to other post events, such as an UpdateCommand.

Routing Key events to other control

Is there any standard way to route all Key events from the control A to other control B? I wish that the keyboard focus will still be on A however the event handler of A would trigger the all event handlers of B for the key events.
edit: Clarification: calling a specific event handler I wrote for B is not enough. I need to mimic the actual event. So for example I want that if a key is sent to a TextBox, it would be written to the TextBox. The solution given below does not do that (not to mention the fact that if new event handlers are added to B it completely fails).
I'm aware that WPF differentiates between logical focus and keyboard focus, but I need both focuses to remain on control A, but in a certain cases route its incoming event to other controls.
Couldn't you do something like this?
private void button1_Click(object sender, RoutedEventArgs e)
{
// Check if the event needs to be passed to button2's handler
if (conditionIsMet)
{
// Send the event to button2
button2.RaiseEvent(e);
}
else
{
// button1's "Click" code
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
// button2's "Click" code
}
Edit: Modified code to use the RaiseEvent() method to programmatically raise a specific event, rather than just calling the event handler for button2.

DataGridView and the CellEndEdit Event

I have a DataGridView, and would like to hook into the CellEndEdit event. I've been able to successfully hook into the CellContentClick event, but am having issues with CellEndEdit.
I added the following code to my Form1.cs file:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellCancelEventArgs e)
{
dataGridView1[0, 0].Value = "Changed";
}
With that code, nothing happens when I am done editing a cell. Is there anything else that I need to do to successfully hook into this event? I see that CellContentClick has a
this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
line of code in the Form1.Designer.cs file, but I tried to mimic this for CellEndEdit, and received a compile error
(No overload for 'dataGridView1_CellEndEdit' matches delegate
'System.Windows.Forms.DataGridViewCellEventHandler')
You could implement this yourself.
In your constructor you could have a HookEvents() method which wires up such events.
Or, within the form designer, click the gridview to select it, go to the properties window and click the yellow thunderbolt to find a list of events. Then, scroll down and find the CellEndEdit event and double click it - this will wire up the event for you.
To wire it up yourself, it may look like:
class A : Form
{
public A()
{
Initialize();
HookEvents();
}
private void HookEvents()
{
dataGridView1.CellEndEdit += dataGridView1_CellEndEdit;
}
}
I doubt very much that your solution would work.
It's not a matter of where you place the subscription, is how you do it.
Brandon, you are declaring an EventHandler, that is the function responsible of doing what you want to do in case of that event "dataGridView1_CellEndEdit" but you are not subscribing to the event. Also in your function you are passing the wrong parameters.
The easy solution is either subscribe from the designer window or by code doing this:
write "dataGridView1.CellEndEdit +=" and then press the TAB buton twice. That shoud create the code for subscription to the event and the correct delegate to handle it.

Categories