0

I cant figure it out why it works this way.

I have two classes which implements interface Pseudo code

Public Interface IChart
{
   void Show()
   void Hide()
}

public class DailyChart: IChart
{
 /***/
  public DailyChart(chartControl, Id)
  {
    chartControl.CustomDraw += new CustomDrawEvent(/**/)
  }
}


public class WeeklyChart: IChart
{
  public WeeklyChart(chartControl, Id)
  {
   chartControl.CustomDraw += CustomDrawEvent(/**/)
}

Then in winforms form I declare an object

IChart object

Then I use combobox to switch between charts at a runtime, which goes like

object = new Weeklychart(chartControl, id)

or

object = new DailyChart(chartControl, id)

And then goes the magic I run app, switch from Weekly to Daily, then to Weekly and it causes error. I've debugged application and found out, that CustomDrawEvent is in BOTH classes simultanously - which obviously cause error, because they have different implementations (but, the correct class is called to create chart)

Anyone knows where is the problem?

Raston
  • 91
  • 2
  • 10
  • 2
    Looks like you have problem because you do not un-subscribe from CustomDraw event of chartControl when switching between classes. I think error details would make problem more clear – Sergey Berezovskiy Feb 24 '14 at 20:00
  • 1
    What's the error that's caused? That's pretty important information to just omit. – Servy Feb 24 '14 at 20:01
  • Ok I've forgotten to add, I've tried to unsubsribe to event - everytime I create class I unsubscribe from event, still it happens, so its not a solution @Servy, out of bound array exception, it can happen there, because it has wrong data in one of the events – Raston Feb 24 '14 at 20:25
  • @Raston Where is the out of bounds error? What method, what is the collection being accessed where does the index come from. Show enough code to replicate the problem. – Servy Feb 24 '14 at 20:27
  • @Servy can't post the full code. Basically WeeklyChart (which should be processed) has correct data in CustomDraw (right scale), but simultanously DailyChart is firing the event and tries to paint in wrong scale, looking for a argument which doesnt exist. I know what causes problem, I just dont know why both events are processed. After I reassign to from DailyChart to WeeklyChart, there should be no connection between those object, right? Tried to unsubscribe event, but it doesnt work either – Raston Feb 24 '14 at 20:53
  • @Raston "Doesn't work" is entirely unhelpful. Do you get an error when trying to unsubscribe from the event, is it firing anyway, how are you unsubscribing from the event, etc. You need to provide enough information for us to replicate the problem. This doesn't mean posting your entire code base, but it does mean posting *something*. You need to take the time to figure out what is relevant to your problem and what isn't in providing your example. – Servy Feb 24 '14 at 20:55
  • @Servy true, "doesnt work" isnt clear. I've tried to unsubscribe exactly as it is proposed in the solution. Unfortunately, it still fires BOTH events, in two classes. Should I implement IDisposable in both classes and dispose one, when combobox selection changes? But then, I use IChart object, so calling dispose on the object will cause nullreferenceexception when assigning second class? – Raston Feb 24 '14 at 21:07
  • 1
    @Raston If you are not properly removing the event handler we need to see how you're trying to remove the event handler. Clearly that's the part of your code that's not working. – Servy Feb 24 '14 at 21:10

2 Answers2

0

Before you add a new event to chart you need to remove the old like this:

chartControl.CustomDraw -= yourOldEvent;
chartControl.CustomDraw += yourNewEvent;

Or you can read this question to remove all the events of control: How to remove all event handlers from a control

Community
  • 1
  • 1
Only a Curious Mind
  • 2,807
  • 23
  • 39
0

*strong text*The problem you're having is that events in .Net can have an unlimited number of handlers (which is why you set and unset with +=/-= rather than just =), and you're passing in the same chartControl object to both classes.

You either need to unsubscribe to the event or create a new instance of the chartControl.

EDIT:

Unsubscribing to events can be tricky. Each object can unsubscribe itself, but not other objects, i.e. an instance of WeeklyChart cannot unsubscribe a DailyChart, or even another instance of WeeklyChart.

What you could do is make a method "Unsubscribe" in both WeeklyChart and DailyChart that you call on the object from wherever you're making/switching these objects around.

So something like this:

public class DailyChart: IChart
{
 /***/
  public DailyChart(chartControl, Id)
  {
    chartControl.CustomDraw += new CustomDrawEvent(/**/);
  }
  public Unsubscribe()
  {
    chartControl.CustomDraw -= new CustomDrawEvent(/**/);
  }

}

public class WeeklyChart: IChart
{
  public WeeklyChart(chartControl, Id)
  {
   chartControl.CustomDraw += CustomDrawEvent(/**/);
  }
  public Unsubscribe()
  {
    chartControl.CustomDraw -= new CustomDrawEvent(/**/);
  }
}

So whenever you're making an instance of either, you clean up the old one first:

mychart = new WeeklyChart(chartControl, Id);

// Do stuff...

myChart.Unsubscribe();

myChart = new MonthlyChart(chartControl, Id);

Or just implement IDisposable and remove it on Dispose().

Seth Moore
  • 3,575
  • 2
  • 23
  • 33
  • Good answer, gonna test it out. I guess I will add Unsubscribe to my interface, which will allow me to do this job on IChart object. Thanks! – Raston Feb 24 '14 at 21:49