Strange? DesignMode Behaviour

C

Charles Law

Further to my issue about user controls, I have a problem with DesignMode.
Here is the project hierarchy:

MainApp
|_ Project1
|_ SubProject (UserControl)

SubProject has a default constructor (New) which does the MyBase.New() thing
and then InitializeComponent().

When I open the Project1 form in the IDE (design time), on which SubProject
is placed, the New method executes, and DesignMode is False. If I then
change a property of SubProject in the property grid (still in Project1)
then DesignMode (in SubProject) is reported as True.

The same thing happens with the SubProject_Load event, that is it reports
DesignMode False when opening the Project1 form in design mode.

Where can I put code that must only run when MainApp runs? Does that all
make sense?

TIA

Charles
 
A

Armin Zingler

Charles Law said:
Further to my issue about user controls, I have a problem with
DesignMode. Here is the project hierarchy:

MainApp
|_ Project1
|_ SubProject (UserControl)

SubProject has a default constructor (New) which does the
MyBase.New() thing and then InitializeComponent().

When I open the Project1 form in the IDE (design time), on which
SubProject is placed, the New method executes, and DesignMode is
False. If I then change a property of SubProject in the property grid
(still in Project1) then DesignMode (in SubProject) is reported as
True.

The same thing happens with the SubProject_Load event, that is it
reports DesignMode False when opening the Project1 form in design
mode.

Where can I put code that must only run when MainApp runs? Does that
all make sense?

I'm not sure if I understand you. The DesignMode property is not set in the
constructor yet.
 
H

Herfried K. Wagner [MVP]

Hello,

Charles Law said:
Further to my issue about user controls, I have a problem
with DesignMode. Here is the project hierarchy:

MainApp
|_ Project1
|_ SubProject (UserControl)

SubProject has a default constructor (New) which does the
MyBase.New() thing and then InitializeComponent().

When I open the Project1 form in the IDE (design time), on
which SubProject is placed, the New method executes,
and DesignMode is False.

If you place a control on a form, it doesn't run in design mode any more. I
currently don't have access to VS.NET, bug you may want to experiment with:

\\\
#If Debug Then
Console.WriteLine("Debug mode.")
#Else
Console.WriteLine("Release mode.")
#End If
///

You can check if a debugger is attached by calling
'System.Diagnostics.Debugger.IsAttached'.
 
F

Fergus Cooney

Hi Charles,

Whose DesignMode are you talking about, ie. what's the object reference?

If it's the UserControl can you check the DesignMode of its Container, and
of the Container's Parent, etc, or whatever.

In other words, check up the chain to see if anyone there is in Design
Mode.

I haven't used any of this myself, but it sort of makes sense that a
UserControl is in DesignMode when you have <its> project open because you add
Controls to it, move them around, etc, - but it's not in Design Mode when it's
on a Form in another project - you can't play with it - except when its
properties are being set. So Project1 would be in Design Mode but UserControl
would not.

Then again, maybe I'm barking up the wrong tree :). Food for thought.

Regards,
Fergus
MVP [Windows Keyboard, PC Power Switch]
 
C

Charles Law

Hi Fergus
I haven't used any of this myself, but it sort of makes sense that a
UserControl is in DesignMode when you have <its> project open because you add
Controls to it, move them around, etc, - but it's not in Design Mode when it's
on a Form in another project - you can't play with it - except when its
properties are being set. So Project1 would be in Design Mode but UserControl
would not.

Yes, that's what I thought would be consistent, but SubProject reports
DesignMode True when I do not have its project open but I am setting one of
its properties in the property grid of Project1. Does that make sense?
However, as Armin indicated, and also makes sense that the design mode is
not set in the constructor. But what about the Load event? That also reports
DesignMode False, so is there indeed an event that fires when the control is
loaded in run-time?

The thing is, I just need a place where I can call initialisation code for
SubProject which must only run when the application is in run-time.

Any ideas?

Charles


Fergus Cooney said:
Hi Charles,

Whose DesignMode are you talking about, ie. what's the object reference?

If it's the UserControl can you check the DesignMode of its Container, and
of the Container's Parent, etc, or whatever.

In other words, check up the chain to see if anyone there is in Design
Mode.

I haven't used any of this myself, but it sort of makes sense that a
UserControl is in DesignMode when you have <its> project open because you add
Controls to it, move them around, etc, - but it's not in Design Mode when it's
on a Form in another project - you can't play with it - except when its
properties are being set. So Project1 would be in Design Mode but UserControl
would not.

Then again, maybe I'm barking up the wrong tree :). Food for thought.

Regards,
Fergus
MVP [Windows Keyboard, PC Power Switch]
 
C

Charles Law

Hi Armin

That makes sense. But what about the Load event?

Basically, I just need somewhere where I can call initialisation code once
when the SubProject is in run-time.

Any ideas?

Charles
 
C

Charles Law

Hi Herfried

The issue is not so much when a debugger is attached, because I may be
running the application from the IDE. The puzzling thing is that SubProject
reports that it is in design mode when changing its properties through the
property grid in Project1, but not when it is loading, i.e. in the Load
event. Is that what you would expect?

The bottom line is, from where can I call initialisation code for SubProject
that only executes when the MainApp is in run-time?

Any ideas?

Charles
 
F

Fergus Cooney

Hi Charles,

|| The thing is, I just need a place where I can call
|| initialisation code for SubProject which must only
|| run when the application is in run-time.

Run through my reply again. What I meant by checking containers and
parents is that if <no-one> is in Design Mode then it must be run-time.

Regards,
Fergus
MVP [Windows Keyboard, PC Power Switch]
 
C

Charles Law

Hi Fergus

Yes, I would, but the code I came up with has a flaw:

<code>
Dim cmp As Component = Me
Dim IsDesignMode As Boolean = False

Do Until cmp Is Nothing
If cmp.DesignMode Then
IsDesignMode = True

Exit Do
End If

cmp = DirectCast(cmp.Container, Component)
Loop

If Not IsDesignMode Then
' Do init stuff
...
End If
</code>

<If cmp.DesignMode Then> won't compile because DesignMode is protected, and
therefore not accessible.

Is there another type that I can cast to that has an accessible DesignMode?

Charles
 
C

Charles Law

Hi Fergus

Did you get my last post? I'm still looking for a way to look up the chain
to see if I'm in design mode. Component.DesignMode is protected so I can't
access it.

Any other thoughts?

Thanks

Charles
 
F

Fergus Cooney

Hi Charles,

I'm sorry that my silence has been so long and so deep. You may have
already found the answer yourself by now but here is what I found.

The DesignMode property is always False in the UserControl's constructor.
This makes sense as the UserControl, at that point, has no context. The other
properties that I examined - Me.Site, Me.Site.DesignMode, Me.Parent,
Me.Parent.Site and Me.Parent.Site.DesignMode all came back with Nothing or
False.

In UserControl_Load(), however, DesignMode works as you'd want it to -
True when in the Designer, False when the app is executing. I also found that
Me.Site is True when designing and False when executing, ditto with
Me.Site.DesignMode and Me.Parent.Site.DesignMode.

The important bit is to test Me.DesignMode in UserControl_Load().

Apologies, if I'm too late, but if so, it's good to know you got ahead.
:)

Regards,
Fergus
 
C

Charles Law

Hi Fergus

I was beginning to think I had said something to offend you. I know the
newsgroups have been extremely tiresome this last week, and I had all but
given up hope of any messages getting through. Like some of the others, I am
currently running at about 200 bogus MS e-mails per day :-(

Thanks for the ideas though. I have not solved the problem exactly, in fact
my app has broken at the moment because I have been refactoring it (I love
that word; it gives an air of authority to the practice of arsing about with
it). I have sorted out most of my erroneous build error problems, at the
expense of functionality, i.e. it doesn't have any anymore. Nevermind, eh!

<Interlude>
....
</Interlude>

I have just been experimenting with Site and stuff in UserControl_Load(),
and I am finding that it is always Nothing; when in the designer and when
the app is running. DesignMode is always False as well.

Could it be anything to do with nested user controls? My hierarchy is:

Solution:
Project1 Project2 Project3 ActiveX Control
|_ Form1
|_________UserControl1
|____________UserControl2
|____________WebBrowser
Control

Project3 needs to know whether it is being loaded in the designer of
Project2 or if the whole app is running. I have a message box in the Load
event of Project3 that displays Me.DesignMode. When I open the designer in
Project2, the message box pops up with False.

Is that what you would expect? Maybe I'm missing something.

Cheers

Charles
 
F

Fergus Cooney

Hi Charles,

|| I was beginning to think I had said something to offend you.

No chance, there, my friend. You may have seen in others threads - if
someone jabs me, I jab back - and with a sharper stick!! You'd know it, lol.

I've not given you the priority that your query deserves. Partly because
I've wasted so much time faffing about trying alternate routes into the
server. Loading, resetting, loading, etc, yawn. But also because I haven't
done a UserControl or played with DesignMode and I was putting it off till I
had a clear mind and a decent block of time. I thought it was going to be
hard - but like so many things in .NET it's extremely easy to get started.
(And then it get's hard - making something that's actually useful!)

|| the newsgroups have been extremely tiresome this last week,

Oh, but haven't they!! :-(( It's 11pm and I've been waiting all day for OE
to get past the 4am posts. [But let's not get me started again..., lol].

I've noticed a cut-down on bogies - down from 15 per hour a week ago to
only 3 last night. Soon, hopefully, soon.

|| Refactoring

It does sound good. ;-) 'Chaos before order' is the catchphrase that I
tend to use.

|| sorted out most of my erroneous build error problems, at the
|| expense of functionality, i.e. it doesn't have any anymore

LOL.

|| I have just been experimenting with Site and stuff in
UserControl_Load(),
|| and I am finding that it is always Nothing; when in the designer and
when
|| the app is running. DesignMode is always False as well.

Well, hot-diggitty-damn!! :-(

I only tried with a Project and a UserControl. I shall have to dig deeper.
It might be handy if you could zip up your Solution and send it to me*. [Put
comments on all the proprietory stuff so I know which bits to try and sell!].
But in the meantime I'll create the same structure as you've shown, and see
what turns up.

Cheers,
Fergus

* You can email me directly if you wish.
 
F

Fergus Cooney

Hi Charles,

It's amazing how something can need so much digging into to investigate
and understand, yet the end result is so trivial as to make you wonder why it
was so hard! This one's been a real struggle.

- but I've had success !! ;-))

I created a nesting level one deeper than yours.
Form
[UC_Outer with UC_Inner with UC_Browser]
[UC_Inner with UC_Browser]
[UC_Browser]

On the Form I had one each of these UCs so it had a three-deep, a
two-deep and a one-deep. Each had a text box showing various states and a
belief about whether the component was in DesignMode or not. The results <are>
based on the depth and have nothing to do with the UC itself.

The top-level Outer, Inner and Browser knew that they were in DesignMode
because the flag was True.

The [Inner within Outer] and the [Browser within the top Inner] both had
DesignMode set to False but they had a Parent whose Site.DesignMode was True.

But the [Browser within Inner within Outer] had DesignMode set to False
<and> had no Parent. In other words it didn't have a clue.

Fortunately, the last one is one level deeper than you are using. So have
a go of this as your test in UC_Load().
InDesignMode = Me.DesignMode Or Me.Parent.Site.DesignMode

Alternatively there's a function in the attached Solution (next post)
which will work for any level (using the go-up-the-chain method that I
proposed oh, so long ago!!)

Regards,
Fergus
 
F

Fergus Cooney

Hi Charles,

I've decided to show the function here.

<code>
'Determine whether an arbitrarily nested UserControl
'is in DesignMode or not.
Public Shared Function OneOfUsIsInDesignMode _
(C As ContainerControl) As Boolean
If C Is Nothing Then _
Return False

If Not C.Site Is Nothing Then _
Return C.Site.DesignMode

Return OneOfUsIsInDesignMode (C.Parent)
End Function
</code>

The Solution Attachment is in the next post and it's there if you want to
see how it all fits together [and to see what lengths I went to! ;-) ] The
Form will appear blank when you first open it because the Solution needs to be
rebuilt first. Then close and open the Form. There will be two text files
(DM-Design.txt and DM-Runtime.txt) written to your %TMP% directory (or C:\ if
there's no %TMP%. which will show the sequence of calls - New, Load, etc. It's
an education if nothing else. ;-)

Regards,
Fergus
 
C

Charles Law

Hi Fergus

What can I say. Thanks for all the investigation. Its amazing to what
lengths one must go to make sense of this kind of thing sometimes.

But ... (and I'm sorry there is a but)

When I opened UC_Inner, UC_Browser certainly showed that it belived that it
was in design mode. I then opened UC_Browser and out a WebBrowser control
onto the control and rebuilt it. I then closed it and opened UC_Inner again,
and it showed that UC_Browser now believed that it was running.

I went back to UC_Browser and removed the browser control, rebuilt it and
opened UC_Inner. UC_Browser now shoed that it was in design mode again.

I think we can safely say that the WebBrowser control is sending it screwy.
Then I had an idea (ting!).

Looking in the InitializeComponent() of UC_Browser, it adds these lines:

<code>
Me.AxWebBrowser1 = New AxSHDocVw.AxWebBrowser
CType(Me.AxWebBrowser1,
System.ComponentModel.ISupportInitialize).BeginInit()
....
CType(Me.AxWebBrowser1, System.ComponentModel.ISupportInitialize).EndInit()
</code>

I commented out the BeginInit() and EndInit() calls, and it goes back to
behaving as expected.

So, what are these lines for? Do we need them? Why has that pink duck only
got one leg?

As an aside, reinstate those lines and select Debug | Exceptions | CLR
Exceptions and set 'Break into the debugger' for 'When the exception is
thrown'.

Now run the whole app. BANG!

<error>
A first chance exception of type
'System.Runtime.InteropServices.COMException' occurred in
system.windows.forms.dll

Additional information: Unknown error
</error>

This occurs on the EndInit() call.

<through gritted teeth>
Suffin' ruffin' grrr rick rastedly.
</through gritted teeth>

What do you reckon?

Charles


Fergus Cooney said:
Hi Charles,

It's amazing how something can need so much digging into to investigate
and understand, yet the end result is so trivial as to make you wonder why it
was so hard! This one's been a real struggle.

- but I've had success !! ;-))

I created a nesting level one deeper than yours.
Form
[UC_Outer with UC_Inner with UC_Browser]
[UC_Inner with UC_Browser]
[UC_Browser]

On the Form I had one each of these UCs so it had a three-deep, a
two-deep and a one-deep. Each had a text box showing various states and a
belief about whether the component was in DesignMode or not. The results
based on the depth and have nothing to do with the UC itself.

The top-level Outer, Inner and Browser knew that they were in DesignMode
because the flag was True.

The [Inner within Outer] and the [Browser within the top Inner] both had
DesignMode set to False but they had a Parent whose Site.DesignMode was True.

But the [Browser within Inner within Outer] had DesignMode set to False
<and> had no Parent. In other words it didn't have a clue.

Fortunately, the last one is one level deeper than you are using. So have
a go of this as your test in UC_Load().
InDesignMode = Me.DesignMode Or Me.Parent.Site.DesignMode

Alternatively there's a function in the attached Solution (next post)
which will work for any level (using the go-up-the-chain method that I
proposed oh, so long ago!!)

Regards,
Fergus
 
H

Herfried K. Wagner [MVP]

Fergus Cooney said:
The Solution is separate so that Herfried can read the previous message
(if he wants) without having to download the attachment.

This won't prevent my newsreader from downloading all the messages
(including the attachments which are part of the message).
 
F

Fergus Cooney

Hi Charles,

Damn server. Your header appeared. I clicked on it and it was promptly
deleted. I had to wait for Google to show me the message several hours later.

|| But ... (and I'm sorry there is a but)

No, no, no..... Lol.

|| ... opened UC_Browser and put a WebBrowser control on it
|| .. and rebuilt it. ... UC_Browser now believed that it was running.

Ah! Now that's not supposed to happen.

|| I commented out the BeginInit() and EndInit() calls, and it goes
|| back to behaving as expected.

Hmm. I repeated what you did, and then did it with another AX control.
Same result.

|| So, what are these lines for? Do we need them?

Later, dude. More important questions first.

|| Why has that pink duck only got one leg?

This is the one that intrigues me. I'm going to leave our little problem
and investigate this one first, if you don't mind waiting ... ;-)

Regards,
Fergus
 
F

Fergus Cooney

Hi Charles,

I hate to admit defeat on a problem but I'm simply stumped. I've searched
the Net, I've called friends, I've been to the library.

I was about to hire a researcher but I decided there's limit to what can
be done.

I have absolutely no idea why the pink duck has only one leg. I suspect
that maybe it isn't a pink duck at all but a red herring in disguise - and its
only experience of 'ducks' is the flock of flamingoes where it lives.

Sorry - I did try. :-((

Regards,
Fergus
 
F

Fergus Cooney

Hi again, Charles,

I'm glad that the BANG! was an aside. At least I hope it was. Are you
saying it's another boulder on the road?? It didn't occur for me (on v2002).

|| <through gritted teeth>
|| Suffin' ruffin' grrr rick rastedly.
|| </through gritted teeth>
||
|| What do you reckon?

I reckon I love that dawg. He gave me much joy when I was a nipper. :)
And isn't it good that we keep good humour in the face of the enemy.


I had a bit more success on the ISupportInitialize interface. :) I've no
idea why it should spoil DesignMode detection but I found out more about it.

It's used by certain controls that need to have several properties setup
before they take action. There's a very good user-defined example here:
http://tinyurl.com/pl6t

I'll summarise it (still long though, pant). It has a TextBox in a UC
which takes a file path, and displays the file in the (multi-line) TextBox.
There is also an Active property which says whether to "do yore thang" or not.
Due to bad programming (for the sake of the example), if you set Active to
True before you set the FilePath, it will crash. In InitialiseComponent, the
Designer writes code to set Active to True before the setting of FilePath,
so - Crash!! By implementing ISupportInitialize, the UC defers any action
until EndInit. Thus it's a hold-yore-hosses bracketing mechanism.

So. The WebBroswer Control that you are using is hosted by an AxHost
Component which implements ISupportInitialize for those hosted ActiveXs that
need it. Your WebBroswer may not need it - especially if you aren't setting
anything that could be 'dangerous'.

Take it out. Take it right out and to hell with it. And let DesignMode be
true and faithful once again. ;-)

Regards,
Fergus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top