tags:

views:

392

answers:

6

I am relatively new to programming, as you will soon see...
I have 2 events, which execute the same code. I currently have the following pseudo code for a datagridview:

private void dgv_CellEnter(object sender, DataGridViewCellEventArgs e)  
{
   string abc = "abc";
}

private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)  
{
   string abc = "abc";
}

Is there a way to combine this into one event? Is there a better way to do this?

+1  A: 

Easiest way is to do this:

private void dgv_CellEnter(object sender, DataGridViewCellEventArgs e)
{ 
    dgv_CellClick(sender, e); 
}

private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
{ 
    string abc = "abc"; 
}

There is code automatically generated by the IDE that wires up your events though, and you could modify this so they both hook up the same event handler, but I don't like messing with generated code.

In ASP.NET or WPF, your data grid or similar has a property that determines the name of the event handler, so you could just point them both to that.

If you were programming in VB.NET instead of C#, you could just write one method and use the Handles keyword to say that this one method handles both events.

Scott Whitlock
...or you could refactor the contents of the event handlers into another method, and have both event handlers call that method.
Scott Whitlock
Beat me to the answer by 3 seconds :)
mlevit
@mlevit - I really took and chance and edited it once after submitting too!
Scott Whitlock
+1  A: 

You could try the following:

private void dgv_CellEnter(object sender, DataGridViewCellEventArgs e)
{
    string abc = "abc";
}

private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
{
    dgv_CellEnter(sender, e);
}

That way when you either Click or push Enter it will run the same method.

Thanks

mlevit
Its probally best to have an intermediary method instead of calling the event handler of a different control
Gregory
+6  A: 

Well the quick answer is yes. put the guts of the methods in its own method and then just have the onclick event call that method. this will give you only one place to update code should it need to change.

there are a 100 different ways to do this, and this is prob the easiest.

so create something like this:

protected void MyNewMethod()
{
    string abc = "123";
}

and then your other methods will just call it like this:

private void dgv_CellEnter(object sender, DataGridViewCellEventArgs e)
{ 
    MyNewMethod(); 
}

private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
{ 
    MyNewMethod(); 
}

Option 2

just call the same method from the markup. you really only need one of those methods and the event in the markup can call the same one.

YetAnotherDeveloper
Regarding Option 2, the question seems to be related to Windows Forms, which doesn't have markup.
Scott Whitlock
Ah... sorry i missed that. it still applies just select the control and bring up the properties window and then select the event "tab". and you can just select the same event from the drop down.
YetAnotherDeveloper
I consider this "the right way to do it."One benefit of doing it this way is that if the events have different signatures, you can still call MyNewMethod().
skypecakes
+2  A: 

In the property window (using C# Express) you can select event handlers in a drop-down, or manually type the name of a method. The signature just has to match. I'm assuming that this is the same in VS.

Snarfblam
+3  A: 

Why not just have one method and map it to two events?

private void dgv_CellEvent(object sender, DataGridViewCellEventArgs e)
{
    string abc = "123";
}

// In the event mapping

dgv.CellEnter += dgv_CellEvent;
dgv.CellClick += dgv_CellEvent;
Andrew Shepherd
Seems like the most concise, "correct" way to do this. Thanks!
muhan
A: 

Ok i have a question that is the same as above:

What if you want to literally combine two events, like

public interface IInterfaceWithEvents
{
    event EventHandler EventFired;
}

public class ClassA : IInterfaceWithEvents
{
    public event EventHandler EventFired;

    public void Invoke()
    {
        if(EventFired != null)
             EventFired(this, EventArgs.Empty);
    }
}

public class ClassB : IInterfaceWithEvents
{
    public event EventHandler EventFired;

    public void Invoke()
    {
        if(EventFired != null)
             EventFired(this, EventArgs.Empty);
    }
}

What I need is to create 'ClassA' and convert it the interface, then from there convert it into a 'ClassB' object. But sadly, C# does not allow this type of casting. Instead I trying to figure out if there is a way to combine the events of the 'ClassA' object with the events of the 'ClassB' object:

ClassA ca;

// the create method returns an IIterfaceWithEvents object created from 
// an external library (so the calling code does not know the literal type that
// is ClassB)
IInterfaceWithEvents i = external.create( some_args ); 

// since this is illegal
ca = (ClassA)i;  //<- exception for wrong cast

// i need to just physically convert the 'i' reference into the 'ClassA' object:

public static ClassA From(IInterfaceWithEvents ievents)
{
    ClassA ca = new ClassA();

    // is there some way to do this:
    ca.EventFired = ievent.EventFired;
}

// if so I could now just do this to convert 'ca' to 'i'
ca = ClassA.From(i); 

// but downside is, if the ClassB (i) reference calls on EventFired then
// the 'ClassA (ca) EventFired event will never be called, and vice-versa

I could get them combined through a delegate, but it really defeats the purpose. And I have to use events and the Interface, if I could use an abstract class I would be all ok here, but sadly I cannot. So my question one more time (just in case the above examples were too crude):

Does C# have a way to pass the reference from one event to another, or literally combine the two events (basically making them the same event).

Or:

Is there a way to just cast 'ClassA' to 'IInterfaceWithEvents' then from 'IInterfaceWithEvents' to ClassB. <- this would be awesome, but I do understand why the CLR does not allow it.

qc.zackf-FissureStudios
You should ask this as a *question*, not post as an *answer*. But ultimately, the point is that you **aren't** doing any conversion here; you are casting. It is true to say that "ClassA : IInterfaceWithEvents" and that "ClassB : IInterfaceWithEvents", but that infers no relationship between ClassA and ClassB - they could be `Car` and `PaperClip` - how do you convert a `Car` into a `PaperClip` ? (not allowing for a big crusher).
Marc Gravell
Well I did ultimately figure it out. Like the car to paperclip theory we have going. Instead of trying to convert the car to paperclip, the car will just pass some of it's materials to the paperclip, making it a piece of the car. This way both objects can be made from the same materials and properties but be have slightly different. Although instead of car it's more like paper-clip to staple.
qc.zackf-FissureStudios