Damn Vegetables
Damn Vegetables

Reputation: 12464

Run code after the caller of the event handler has exited

In the following example, Is it possible to execute Do X after the control's Do Y is done (i.e., exited the method in which my event handler is called)? It seems the action of Do X messes up with Do Y, so Do X needs to be done after Do Y is done.

//at form initialisation
someThirdPartyControl.MouseDoubleClick += MyHandler;

void MyHandler(...)
{
    e.Handled = true;
    //Do X
}

//The control's code may be something like
class SomeThirdPartyControl:Control
{
  void override OnMouseDoubleClick(...)
  {
     //call event handlers
     //Do Y
  }
}

Do X potentially changes the size of the control, so that the location of the items may change, and when that happens the control wrongly selects the item where the mouse pointer is after the double click. For example, I double-clicked Item 4, but Do X changes the control's size, and after Do X is done, Item 2 is beneath the mouse pointer, and the control selects Item 2. What I want is that the selected item remains Item 4.

Upvotes: 3

Views: 679

Answers (3)

P. Kouvarakis
P. Kouvarakis

Reputation: 1943

You can only do this if you subclass SomeControl and override OnMouseDoubleClick like this:

class MyControl:SomeControl
{
  void override OnMouseDoubleClick(MouseEventArgs e)
  {
     base.OnMouseDoubleClick(e)
     //call event handlers
     //Do X
  }
}

You could even go as far as defining a new event AfterMouseDoubleClick and fire that event instead of calling X in OnMouseDoubleClick.

class MyControl:SomeControl
{
  public event MouseButtonEventHandler AfterMouseDoubleClick;

  void override OnMouseDoubleClick(MouseEventArgs e)
  {
     base.OnMouseDoubleClick(e)
     //call event handlers
     OnAfterMouseDoubleClick(e)
  }

  void virtual OnAfterMouseDoubleClick(MouseEventArgs e)
  {
     if(AfterMouseDoubleClick != null)
       AfterMouseDoubleClick(this, e)
  }
}

However you should really consider what you are doing in X to mess up Y.

Upvotes: 1

Scott Chamberlain
Scott Chamberlain

Reputation: 127553

Yes, it is very easy, you just need to inherit from SomeThirdPartyControl. You could even turn it in to another event and use it that way.

class MyWrapperControl : SomeThirdPartyControl
{
  public event MouseEventHandler AfterMouseDoubleClick;

  protected void override OnMouseDoubleClick(MouseEventArgs e)
  {
     base.OnMouseDoubleClick(e); //This will Do X.

     OnAfterMouseDoubleClick(e);
  }

  protected virtal void OnAfterMouseDoubleClick(MouseEventArgs e)
  {
       var temp = AfterMouseDoubleClick;
       if(temp != null)
           temp(this, e);
  }
}

used like.

//at form initialisation
myWrapperControl.AfterMouseDoubleClick += MyHandler;

void MyHandler(object sender, MouseEventArgs e)
{
    //This event is fired after all MouseDoubleClick events have been handled.

    //Do X
}

Upvotes: 0

areller
areller

Reputation: 5238

The base implementation of OnMouseDoubleClick calls the event, so:

  1. MyHandler won't be fired if you don't call the base implementation from OnMouseDoubleClick()

  2. You can control the order of invocation by putting base.OnMouseDoubleClick() wherever you need it to be.

    void override OnMouseDoubleClick(...)
    {
        // ...
        // Do Y
        base.OnMouseDoubleClick(); // Does X among other things...
    }
    

Upvotes: 0

Related Questions