views:

170

answers:

3

I'm implementing a project in MVP pattern and I've got some interfaces like this:

public interface IWizardStep {
  event EventHandler NextStep;
}

public interface ISubmitable {
  event EventHandler Submit;
}

 public interface IStep : ISubmitable, IWizardStep {
  string SomeProperty { get; set; }
 }

My presenter class then has this:

public class StepPresenter {
  public IStep View { get; set; }

  public StepPresenter() {
    this.View.Submit += new EventHandler(StepSubmitted);
  }

  void StepSubmitted(object sender, EventArgs e){
    //do some processing

    //Now I want to raise the Next event
    //this.View.NextStep(sender, e) throws a compile error
  }

}

So I'm getting a compile error when trying to raise the NextStep event on the within the View. I'm pretty sure that it's a problem because I haven't implemented an event handler for NextStep, but this presenter wont be handling the event.

The presenter will be implemented as 1 step of many in a wizard on a form (ASP.NET, but that doesn't make any difference) and the wizard will catch the NextStep event and show the next step in the wizard.

So how can I have an event on an interface raised like this, or is it impossible?

A: 

Hi Slace

This is because NextStep is an eventHandler. You cannot call an event handler which must be raised. I would expect IStep to have a method call such as MoveToStep() which the concrete implementation would raise the event as expected which you could subscribe to somewhere else.

What is your reasoning for the NextStep eventHandler in IWizardStep? If its a methd you're after, create that in your interface instead of an event. Your consumer class should expect to call a method when needing to "do" something and subscribe to an event when the IWizardStep has something to pass back (data or whatever)

Ray Booysen
A: 

@Ray Booysen:

Yep, I realised just after posting this that I shouldn't be trying to raise the event on the interface, but I should be calling a method which raises the event in the View. So I've modified my interfaces and classes like this:

public interface IWizardStep<TEventArgs> {
  event EventHandler<TEventArgs> NextStep;

  void RaiseNextStep<TSender>(TSender sender, TEventArgs e);
}

public class Step {
  void StepSubmitted(object sender, EventArgs e) {
    this.View.RaiseNextStep(sender, e);
  }
}

Then on the View implementation I have:

public void RaiseNextStep<TSender>(TSender sender, EventArgs e) {
  if(this.NextStep != null) this.NextStep(sender, e);
}
Slace
Hi Slace. You should make the IWizardStep method only take the data it needs. Does it require the sender and event args? Or might it only require a smaller set of data?
Ray Booysen
It may, which is why it's being passed. But the args are generic so it can easily be custom args. Really I just kept it all there for demo purposes
Slace
A: 

OP Does this work for you? I am trying to do somthing similer but i cant seem to get it working. I was wonering if you could explain it more in depth. thanks

bump

Yes, Ray's answer was correct and my answer shows the code you need to make it work
Slace