Interfaces

  • Thread starter Thread starter Graham McKechnie
  • Start date Start date
G

Graham McKechnie

Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into a
corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as GPSSurveyForm - so
the this.form.GetInvoker is strongly typed to GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class, so
"this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both those
forms would inherit from, but I'm really struggling getting it to work as
this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker();
void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH
 
....I agree... or if SafeCallEventHandler was not a member of your
GPSSurveyForm (it is not clear from your description), then you can omit
that method from the interface definition and change GetInvoker to return
the appropriate type.

There is an alternative approach to interfaces (and I'd really need more
info in order to recommend one over the other).

Rather than pass the form to the ctor of GPSSurveyForm, pass a delegate
pointing to GetInvoker. When you create the delegate, you decide to which
form's method it points to. The resulting calling code would be like this:

// mSomeDel is the instance of the delegate passed at ctor
this.mSomeDel.SafeCallEventHandler(new EventHandler(_OnPositionReceived),
this, e);

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Sergey Bogdanov said:
If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham said:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into a
corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as GPSSurveyForm -
so the this.form.GetInvoker is strongly typed to GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class, so
"this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both those
forms would inherit from, but I'm really struggling getting it to work as
this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Sergey and Daniel,

Thanks very much for your responses. Perhaps the example I gave you was a
touch too complicated for what I was really trying to describe and didn't
really convey what I was having difficulty understanding.

I've gone a route that I suppose is a combination of your replies for this
particular problem. But I would like to ask you both for further assistance
in understanding Interfaces. I'm just having a hard time getting my head
around them. I wasn't even sure that an interface was what was required, but
I just couldn't find another way, so I started thinking about what
interfaces could do for the problem I was having.

This is what I've gone with so far for the example I quoted.

public interface IConsumer
{
IConsumer Owner
{
get;
}
Invoker GetInvoker();
}

In GPSSurveyForm I declare

private IConsumer owner;
public IConsumer Owner
{
get { return owner;}
}
private Invoker invoker;

In the constructor of GPSSurveyForm I instantiate gpsInterpreter and pass in
owner, previously I was passing in GPSSurveyForm to gpsInterpreter, so now
there is no reference to GPSSurveyForm in GPSInterpreter.

owner = this;
this.gpsInterpreter = new GPSInterpreter(owner);
invoker = new Invoker(this);

I've also got the following in GPSSurveyForm
public Invoker GetInvoker()
{
return invoker;
}

so the code in GPSInterpreter now looks like this
private IConsumer owner; // new variable, replaces the old form
variable

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
{
this.owner.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}
}

Just a very subtle change for the event handler, but it all appears to work
as you guys predicted. I haven't as yet got around to the next window that
will also require the GPSInterpreter, but I presume if it also inherits from
IConsumer it will also work ok to.

I've always had problems with C# when passing a window to another class and
then wanting to refer back to some variable or method of the original
window. eg here is some old code that I've used for awhile for populating
tables as they come from the desktop. Perhaps it comes from habits developed
using my previous programming language.

((SyncForm)owner).ProgressBar.NextPosition( "Copying Players..." );
PopulatePlayers();

In this case I just wanted a reference to the ProgressBar control, but
obviously this is going to be a problem if I ever want to run this code from
some other window other than Syncform. Its never happened, but you probably
get my drift.

So this technique of using interfaces would also get around this type of
coding as well?

I hope I'm going down the right track with my thinking and would really
appreciate your thoughts re this new approach.

Regards
Graham



Sergey Bogdanov said:
If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham said:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into a
corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as GPSSurveyForm -
so the this.form.GetInvoker is strongly typed to GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class, so
"this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both those
forms would inherit from, but I'm really struggling getting it to work as
this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Graham I haven't gone through your code.

I suggest you pick up an OO book. Also use online resources, e.g. this:
http://msdn.microsoft.com/library/d...vbcon/html/vbconDefiningYourOwnInterfaces.asp

In general, give some thought to your application's design/architecture.
Then you'll know what elements of a form have to be available to another
form and you can abstract them into their own structure rather than
providing direct access to them (e.g. put them in a singleton/static class).

Another approach is to forget the "what if" scenarios and deal with the
problems as and when they arrive.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Graham McKechnie said:
Sergey and Daniel,

Thanks very much for your responses. Perhaps the example I gave you was a
touch too complicated for what I was really trying to describe and didn't
really convey what I was having difficulty understanding.

I've gone a route that I suppose is a combination of your replies for this
particular problem. But I would like to ask you both for further
assistance in understanding Interfaces. I'm just having a hard time
getting my head around them. I wasn't even sure that an interface was what
was required, but I just couldn't find another way, so I started thinking
about what interfaces could do for the problem I was having.

This is what I've gone with so far for the example I quoted.

public interface IConsumer
{
IConsumer Owner
{
get;
}
Invoker GetInvoker();
}

In GPSSurveyForm I declare

private IConsumer owner;
public IConsumer Owner
{
get { return owner;}
}
private Invoker invoker;

In the constructor of GPSSurveyForm I instantiate gpsInterpreter and pass
in owner, previously I was passing in GPSSurveyForm to gpsInterpreter, so
now there is no reference to GPSSurveyForm in GPSInterpreter.

owner = this;
this.gpsInterpreter = new GPSInterpreter(owner);
invoker = new Invoker(this);

I've also got the following in GPSSurveyForm
public Invoker GetInvoker()
{
return invoker;
}

so the code in GPSInterpreter now looks like this
private IConsumer owner; // new variable, replaces the old form
variable

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
{
this.owner.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}
}

Just a very subtle change for the event handler, but it all appears to
work as you guys predicted. I haven't as yet got around to the next window
that will also require the GPSInterpreter, but I presume if it also
inherits from IConsumer it will also work ok to.

I've always had problems with C# when passing a window to another class
and then wanting to refer back to some variable or method of the original
window. eg here is some old code that I've used for awhile for populating
tables as they come from the desktop. Perhaps it comes from habits
developed using my previous programming language.

((SyncForm)owner).ProgressBar.NextPosition( "Copying Players..." );
PopulatePlayers();

In this case I just wanted a reference to the ProgressBar control, but
obviously this is going to be a problem if I ever want to run this code
from some other window other than Syncform. Its never happened, but you
probably get my drift.

So this technique of using interfaces would also get around this type of
coding as well?

I hope I'm going down the right track with my thinking and would really
appreciate your thoughts re this new approach.

Regards
Graham



Sergey Bogdanov said:
If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham said:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into a
corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as GPSSurveyForm -
so the this.form.GetInvoker is strongly typed to GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class, so
"this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both those
forms would inherit from, but I'm really struggling getting it to work
as this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Daniel,
Graham I haven't gone through your code.
Well you usually ask for code samples, so I thought I'd post it. Maybe
you'll get to it when you have more time.
I suggest you pick up an OO book. Also use online resources, e.g. this:
Thanks for the link. I do have many C# books, but none of them really do a
lot with interfaces. Have you a recommendation on one that does?

Regards
Graham


Daniel Moth said:
Graham I haven't gone through your code.

I suggest you pick up an OO book. Also use online resources, e.g. this:
http://msdn.microsoft.com/library/d...vbcon/html/vbconDefiningYourOwnInterfaces.asp

In general, give some thought to your application's design/architecture.
Then you'll know what elements of a form have to be available to another
form and you can abstract them into their own structure rather than
providing direct access to them (e.g. put them in a singleton/static
class).

Another approach is to forget the "what if" scenarios and deal with the
problems as and when they arrive.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Graham McKechnie said:
Sergey and Daniel,

Thanks very much for your responses. Perhaps the example I gave you was a
touch too complicated for what I was really trying to describe and didn't
really convey what I was having difficulty understanding.

I've gone a route that I suppose is a combination of your replies for
this particular problem. But I would like to ask you both for further
assistance in understanding Interfaces. I'm just having a hard time
getting my head around them. I wasn't even sure that an interface was
what was required, but I just couldn't find another way, so I started
thinking about what interfaces could do for the problem I was having.

This is what I've gone with so far for the example I quoted.

public interface IConsumer
{
IConsumer Owner
{
get;
}
Invoker GetInvoker();
}

In GPSSurveyForm I declare

private IConsumer owner;
public IConsumer Owner
{
get { return owner;}
}
private Invoker invoker;

In the constructor of GPSSurveyForm I instantiate gpsInterpreter and pass
in owner, previously I was passing in GPSSurveyForm to gpsInterpreter, so
now there is no reference to GPSSurveyForm in GPSInterpreter.

owner = this;
this.gpsInterpreter = new GPSInterpreter(owner);
invoker = new Invoker(this);

I've also got the following in GPSSurveyForm
public Invoker GetInvoker()
{
return invoker;
}

so the code in GPSInterpreter now looks like this
private IConsumer owner; // new variable, replaces the old form
variable

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
{
this.owner.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}
}

Just a very subtle change for the event handler, but it all appears to
work as you guys predicted. I haven't as yet got around to the next
window that will also require the GPSInterpreter, but I presume if it
also inherits from IConsumer it will also work ok to.

I've always had problems with C# when passing a window to another class
and then wanting to refer back to some variable or method of the original
window. eg here is some old code that I've used for awhile for populating
tables as they come from the desktop. Perhaps it comes from habits
developed using my previous programming language.

((SyncForm)owner).ProgressBar.NextPosition( "Copying Players..." );
PopulatePlayers();

In this case I just wanted a reference to the ProgressBar control, but
obviously this is going to be a problem if I ever want to run this code
from some other window other than Syncform. Its never happened, but you
probably get my drift.

So this technique of using interfaces would also get around this type of
coding as well?

I hope I'm going down the right track with my thinking and would really
appreciate your thoughts re this new approach.

Regards
Graham



Sergey Bogdanov said:
If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham McKechnie wrote:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into a
corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as GPSSurveyForm -
so the this.form.GetInvoker is strongly typed to GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class,
so "this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both those
forms would inherit from, but I'm really struggling getting it to work
as this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Well you usually ask for code samples, so I thought I'd post it. Maybe
If there is a specific coding problem then yes a sample (i.e. something I
can *run* here) is good.
lot with interfaces. Have you a recommendation on one that does?
Sorry not really. Any OO book would do. If you follow the msdn link I gave
you though (and the section it belongs to:
http://msdn.microsoft.com/library/d.../vbcon/html/vboriinterfaceabstractclasses.asp),
you should find enough to keep you happy. If I must give you a
recommendation on an excellent OO book then go for this one (somewhere there
you'll find my full review):
http://www.amazon.com/exec/obidos/r...=1789&tag=danielmoth-20&creative=9325

Going back to your previous post. You changed your code and it worked for
you. You then seek confirmation that if you added a new form it would also
implement IConsumer. The answer is "yes"... I kinda treated that as a
rhetorical question :-)


To be honest though, especially on an embedded device, I tend to not worry
too much with the most extensible design that captures all "what if"
scenarios. Just pass the owner form to the child form so the child has
access to its data. Sure if it is a case of a single field or a structure
then using an interface or a shared singleton is OK but if you are going to
be sharing UI elements and a whole bunch of data then your design has them
tightly coupled already so you might as well have them know each other
explicitly.

Hope this helps.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Graham McKechnie said:
Daniel,
Graham I haven't gone through your code.
Well you usually ask for code samples, so I thought I'd post it. Maybe
you'll get to it when you have more time.
I suggest you pick up an OO book. Also use online resources, e.g. this:
Thanks for the link. I do have many C# books, but none of them really do a
lot with interfaces. Have you a recommendation on one that does?

Regards
Graham


Daniel Moth said:
Graham I haven't gone through your code.

I suggest you pick up an OO book. Also use online resources, e.g. this:
http://msdn.microsoft.com/library/d...vbcon/html/vbconDefiningYourOwnInterfaces.asp

In general, give some thought to your application's design/architecture.
Then you'll know what elements of a form have to be available to another
form and you can abstract them into their own structure rather than
providing direct access to them (e.g. put them in a singleton/static
class).

Another approach is to forget the "what if" scenarios and deal with the
problems as and when they arrive.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Graham McKechnie said:
Sergey and Daniel,

Thanks very much for your responses. Perhaps the example I gave you was
a touch too complicated for what I was really trying to describe and
didn't really convey what I was having difficulty understanding.

I've gone a route that I suppose is a combination of your replies for
this particular problem. But I would like to ask you both for further
assistance in understanding Interfaces. I'm just having a hard time
getting my head around them. I wasn't even sure that an interface was
what was required, but I just couldn't find another way, so I started
thinking about what interfaces could do for the problem I was having.

This is what I've gone with so far for the example I quoted.

public interface IConsumer
{
IConsumer Owner
{
get;
}
Invoker GetInvoker();
}

In GPSSurveyForm I declare

private IConsumer owner;
public IConsumer Owner
{
get { return owner;}
}
private Invoker invoker;

In the constructor of GPSSurveyForm I instantiate gpsInterpreter and
pass in owner, previously I was passing in GPSSurveyForm to
gpsInterpreter, so now there is no reference to GPSSurveyForm in
GPSInterpreter.

owner = this;
this.gpsInterpreter = new GPSInterpreter(owner);
invoker = new Invoker(this);

I've also got the following in GPSSurveyForm
public Invoker GetInvoker()
{
return invoker;
}

so the code in GPSInterpreter now looks like this
private IConsumer owner; // new variable, replaces the old form
variable

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
{
this.owner.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}
}

Just a very subtle change for the event handler, but it all appears to
work as you guys predicted. I haven't as yet got around to the next
window that will also require the GPSInterpreter, but I presume if it
also inherits from IConsumer it will also work ok to.

I've always had problems with C# when passing a window to another class
and then wanting to refer back to some variable or method of the
original window. eg here is some old code that I've used for awhile for
populating tables as they come from the desktop. Perhaps it comes from
habits developed using my previous programming language.

((SyncForm)owner).ProgressBar.NextPosition( "Copying Players..." );
PopulatePlayers();

In this case I just wanted a reference to the ProgressBar control, but
obviously this is going to be a problem if I ever want to run this code
from some other window other than Syncform. Its never happened, but you
probably get my drift.

So this technique of using interfaces would also get around this type of
coding as well?

I hope I'm going down the right track with my thinking and would really
appreciate your thoughts re this new approach.

Regards
Graham



If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham McKechnie wrote:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into
a corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as
GPSSurveyForm - so the this.form.GetInvoker is strongly typed to
GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class,
so "this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both
those forms would inherit from, but I'm really struggling getting it
to work as this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Daniel,

Thanks for your help. No wonder you didn't want to comment on that code I
posted yesterday. It worked, but I fluked it. I think I've now got a better
understanding of interfaces after showing the code to a colleague. He
pointed out my mistakes.

Graham


Daniel Moth said:
Well you usually ask for code samples, so I thought I'd post it. Maybe
If there is a specific coding problem then yes a sample (i.e. something I
can *run* here) is good.
lot with interfaces. Have you a recommendation on one that does?
Sorry not really. Any OO book would do. If you follow the msdn link I gave
you though (and the section it belongs to:
http://msdn.microsoft.com/library/d.../vbcon/html/vboriinterfaceabstractclasses.asp),
you should find enough to keep you happy. If I must give you a
recommendation on an excellent OO book then go for this one (somewhere
there you'll find my full review):
http://www.amazon.com/exec/obidos/r...=1789&tag=danielmoth-20&creative=9325

Going back to your previous post. You changed your code and it worked for
you. You then seek confirmation that if you added a new form it would also
implement IConsumer. The answer is "yes"... I kinda treated that as a
rhetorical question :-)


To be honest though, especially on an embedded device, I tend to not worry
too much with the most extensible design that captures all "what if"
scenarios. Just pass the owner form to the child form so the child has
access to its data. Sure if it is a case of a single field or a structure
then using an interface or a shared singleton is OK but if you are going
to be sharing UI elements and a whole bunch of data then your design has
them tightly coupled already so you might as well have them know each
other explicitly.

Hope this helps.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Graham McKechnie said:
Daniel,
Graham I haven't gone through your code.
Well you usually ask for code samples, so I thought I'd post it. Maybe
you'll get to it when you have more time.
I suggest you pick up an OO book. Also use online resources, e.g. this:
Thanks for the link. I do have many C# books, but none of them really do
a
lot with interfaces. Have you a recommendation on one that does?

Regards
Graham


Daniel Moth said:
Graham I haven't gone through your code.

I suggest you pick up an OO book. Also use online resources, e.g. this:
http://msdn.microsoft.com/library/d...vbcon/html/vbconDefiningYourOwnInterfaces.asp

In general, give some thought to your application's design/architecture.
Then you'll know what elements of a form have to be available to another
form and you can abstract them into their own structure rather than
providing direct access to them (e.g. put them in a singleton/static
class).

Another approach is to forget the "what if" scenarios and deal with the
problems as and when they arrive.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Sergey and Daniel,

Thanks very much for your responses. Perhaps the example I gave you was
a touch too complicated for what I was really trying to describe and
didn't really convey what I was having difficulty understanding.

I've gone a route that I suppose is a combination of your replies for
this particular problem. But I would like to ask you both for further
assistance in understanding Interfaces. I'm just having a hard time
getting my head around them. I wasn't even sure that an interface was
what was required, but I just couldn't find another way, so I started
thinking about what interfaces could do for the problem I was having.

This is what I've gone with so far for the example I quoted.

public interface IConsumer
{
IConsumer Owner
{
get;
}
Invoker GetInvoker();
}

In GPSSurveyForm I declare

private IConsumer owner;
public IConsumer Owner
{
get { return owner;}
}
private Invoker invoker;

In the constructor of GPSSurveyForm I instantiate gpsInterpreter and
pass in owner, previously I was passing in GPSSurveyForm to
gpsInterpreter, so now there is no reference to GPSSurveyForm in
GPSInterpreter.

owner = this;
this.gpsInterpreter = new GPSInterpreter(owner);
invoker = new Invoker(this);

I've also got the following in GPSSurveyForm
public Invoker GetInvoker()
{
return invoker;
}

so the code in GPSInterpreter now looks like this
private IConsumer owner; // new variable, replaces the old form
variable

protected virtual void OnPositionReceived(PositionReceivedEventArgs e)
{
if ( PositionReceived != null )
{
this.owner.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}
}

Just a very subtle change for the event handler, but it all appears to
work as you guys predicted. I haven't as yet got around to the next
window that will also require the GPSInterpreter, but I presume if it
also inherits from IConsumer it will also work ok to.

I've always had problems with C# when passing a window to another class
and then wanting to refer back to some variable or method of the
original window. eg here is some old code that I've used for awhile for
populating tables as they come from the desktop. Perhaps it comes from
habits developed using my previous programming language.

((SyncForm)owner).ProgressBar.NextPosition( "Copying Players..." );
PopulatePlayers();

In this case I just wanted a reference to the ProgressBar control, but
obviously this is going to be a problem if I ever want to run this code
from some other window other than Syncform. Its never happened, but you
probably get my drift.

So this technique of using interfaces would also get around this type
of
coding as well?

I hope I'm going down the right track with my thinking and would really
appreciate your thoughts re this new approach.

Regards
Graham



If I correctly understood you then all what you need is just to define
interface:

public interface IConsumer
{
IConsumer GetInvoker(); void SafeCallEventHandler(...);
}

Then modify your GPSInterpreter that takes in constructor defined
interface instead of GPSSurveyForm. And all forms which should use the
GPSInterpreter class must implement IConsumer interface:

public class GPSSurveyForm : Form, IConsumer
{
...
}

HTH

--
Sergey Bogdanov [.NET CF MVP, MCSD]
http://www.sergeybogdanov.com


Graham McKechnie wrote:
Hi all

I've got some code that looks like the following.

protected virtual void OnPositionReceived(PositionReceivedEventArgs
e)
{
if ( PositionReceived != null )
this.form.GetInvoker().SafeCallEventHandler( new
EventHandler(_OnPositionReceived), this, e );
}

The code is working ok, but I've just found out I've back myself into
a corner with the way I've designed my GPSInterpreter class, and I'm
struggling to get around the problem.

The variable form is passed in the ctor of the class as
GPSSurveyForm - so the this.form.GetInvoker is strongly typed to
GPSSurveyForm.

I now want another form to also instantiate the GPSInterpreter class,
so "this.form" would then refer to another form.

I somehow feel the way around this is with an Interface that both
those forms would inherit from, but I'm really struggling getting it
to work as this is my first stab at Interfaces.

Maybe I'm going down the wrong track - I'd appreciate any advice.

Regards
Graham
 
Back
Top