Thanks Ian,
This does solve the one issue but creates another.
What happens when the component is not created in a
IDesignerHost enviornment.
I took a look at ILDASM for System.Timers.Timer. It
seems (I am no IL pro) they are not creating or using
a message loop directly (HWND is null) and just making
use of a timer callback. My code requires a message
loop and my first designs borrowed an existing forms
loop. Now I just create my own (via NativeWindow) and
it seems to function well.
I have learned a lot about components on this simple
project - including this new knowledge you have
imparted here. I am surprised that the parent
component of a properly implemented child component is
not readily apparent at runtime.
Thanks again,
Michael Potter
--- Ian Griffiths <[EMAIL PROTECTED]> wrote:
> "Michael Potter" <[EMAIL PROTECTED]> wrote:
>
> > 2) A "System.ComponentModel.Component" derivative.
> > Better, but requires that the developer remembers
> to
> > send the component a reference to the window it is
> > attached to.
>
> Not strictly true - the System.Timers.Timer class
> automatically arranges for
> its SynchronizingObject property to refer to the
> containing Form when it is
> placed on a form, without requiring users to write
> this code themselves.
> (The relevant property gets set in the
> InitializeComponent method, but this
> happens automatically.)
>
> You can do this yourself:
>
> using System.Windows.Forms;
> using System.ComponentModel;
> using System.ComponentModel.Design;
>
> public class ContainedByWindow : Component
> {
>
> public Form ContainingForm {
> get {
> if (cf == null) {
> if (DesignMode) {
> // See if we're being hosted in VS.NET (or
> something similar)
> IDesignerHost dh =
> this.GetService(typeof(IDesignerHost)) as
> IDesignerHost;
> if (dh != null) {
> cf = dh.RootComponent as Form;
> }
> }
> }
>
> return cf;
> }
> set { cf = value; }
> }
> private Form cf;
>
> }
>
> This detects when it is being hosted in VS.NET (or
> any other environment
> that provides the IDesignerHost interface) and
> obtains a reference to the
> containing form if there is one. VS.NET will detect
> that the property's
> value is referring to the form, and correctly
> serializes this in the
> InitializeComponent method as:
>
> this.containedByWindow1.ContainingForm = this;
>
> So that's the code you want, but VS.NET will
> generate it automatically,
> meaning your users are no longer required to
> remember to type it.
>
> Hope that helps,
>
> --
> Ian Griffiths
> DevelopMentor
>
> You can read messages from the Advanced DOTNET
> archive, unsubscribe from Advanced DOTNET, or
> subscribe to other DevelopMentor lists at
http://discuss.develop.com.
__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com
You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.