Resolved My MessageBox Shows aftr ReBuild Solution

aaaron

Well-known member
Joined
Jan 23, 2011
Messages
216
Programming Experience
10+
I think this is going to be tough to describe.

I write to the registry.

In the write method I check the key and if it is not what I expect I show a MessageBox

When I do a Rebuild Solution after the following message:

========== Rebuild All: 62 succeeded, 0 failed, 0 skipped ==========

the MessageBox pops up.

I tried multiple times with the same result.

The last time this happened I had about 20 files opened. I closed all tabs and tried again twice.

Both times I did not get the message.

Seems one or more of my many files is causing the problem simply by being open at the build time.

Got any idea what happens after the build message displays that could cause this.

How about, what method (like maybe New, OnLoad... ) might run (maybe in the designer) after Rebuild
 
Solution
Designer calls parameterless constructor sometimes, both for forms and controls. (and IContainer constructor for component that doesn't have parameterless constructor)

DesignMode property is always False in constructors. This works in constructor: LicenseManager.UsageMode = LicenseUsageMode.Designtime
How about you show us the code that displays that message box and tell us exactly where it is? There's no point our speculating on what it might be, only for you to tell us that it doesn't apply because of some reason that you could have told us beforehand. You provide all the relevant information and we'll work from that. If we need more, we'll ask.
 
I was hoping you had some idea of what type of methods run after the build. I have no idea what code to show. Basically, I was looking for help in finding it. I have no idea at all where to look.

I'm guessing now that maybe the designer runs after a build. If so, I wish I knew which of my files it runs.

I, of course, know the method that contains the Messagebox. But that is not much help as it is called from hundreds of places.

It just occurred to me that if I had a good way to check if that code is running while in design, I could put a check in there and junp over the Messagebox when in design, to see if that helps.

It would at least tell me if it's happening in design.
 
Last edited:
I've rebuilt the solution with various form displayed so often it's a wonder VS doesn't do it without being asked.

Anyway, I found one form that displays ok in the designer.

But if it's showing when I rebuild I get the message.

If it's open (I.E., there is a tab but it's not selected) I don't get the message.
EDIT. This is not true. I just got the message when it was not showing!

So I what would help a lot to know is simply:

What events and methods (if any) does the designer raise when displaying a form.

Even if you don't know but have a guess I like to know it (I imagine it not the kind of thing many people know).
 
Last edited:
Designer calls parameterless constructor sometimes, both for forms and controls. (and IContainer constructor for component that doesn't have parameterless constructor)

DesignMode property is always False in constructors. This works in constructor: LicenseManager.UsageMode = LicenseUsageMode.Designtime
 
Solution
Designer calls parameterless constructor sometimes, both for forms and controls. (and IContainer constructor for component that doesn't have parameterless constructor)

DesignMode property is always False in constructors. This works in constructor: LicenseManager.UsageMode = LicenseUsageMode.Designtime


You always seem to understand my questions.

This does not solve because I already tried commenting out InitializeComponent() in New.

But it helps immensely in reducing what I should take time checking.

1) I'm not sure if you're telling me that only what you mentioned gets called.

2) Just to be absolutely sure: OnLoad is not called by the designer. Right?

3) Is the constructors the only place I should check for design mode?

Thanks'
 
Load event of designed form is not raised, but Load event of user controls and for example a base form that the designed form inherits from is raised.
 
DesignMode property is always False in constructors. This works in constructor: LicenseManager.UsageMode = LicenseUsageMode.Designtime
One question that as more Internet hits than are useful is: How to check to see if code is running in designer.

Uncountable Internet post that claim to describe the best method only to followed by a posts that say the method has a problem.

Your post seems to solve half the problem.

Any suggestion as to how to check for "in designer" in methods that are not a constructor?


BTW. I've searched this forum and could not get any hits for that question. Maybe I just don't have the right search pattern
 
Load event of designed form is not raised, but Load event of user controls and for example a base form that the designed form inherits from is raised.

I could really use the answer to two questions because I have no idea how to check them myself.

1) Does the designer call the following sub?
Protected Overrides Sub Dispose(disposing As Boolean)

2) Does the following check for in designer always work in the above sub:
Return LicenseManager.UsageMode = LicenseUsageMode.Designtime
 
Here's an exercise for you: create a new Windows Forms project and add a Utils module:
VB.NET:
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Module Utils
    Public Sub Debugs(caller As Object, DesignMode As Boolean, <CallerMemberName> Optional name As String = "")
        If DesignMode Then
            Debug.WriteLine($"{caller.GetType.Name} {name} DesignMode")
        ElseIf LicenseManager.UsageMode = LicenseUsageMode.Designtime Then
            Debug.WriteLine($"{caller.GetType.Name} {name} DesignTime")
        Else
            Debug.WriteLine($"{caller.GetType.Name} {name} not DesignMode/DesignTime")
        End If
    End Sub

End Module
Add a class MyTextBox:
VB.NET:
Public Class MyTextBox : Inherits TextBox

    Public Sub New()
        Debugs(Me, DesignMode)
    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        MyBase.Dispose(disposing)
        Debugs(Me, DesignMode)
    End Sub

    Private Sub MyTextBox_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
        Debugs(Me, DesignMode)
    End Sub
End Class
Add a UserControl, add code:
VB.NET:
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Debugs(Me, DesignMode)
End Sub

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Debugs(Me, DesignMode)
End Sub

Private Sub UserControl1_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
    Debugs(Me, DesignMode)
End Sub
In the default Form1 add these:
VB.NET:
Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Debugs(Me, DesignMode)
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Debugs(Me, DesignMode)
End Sub

Private Sub Form1_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
    Debugs(Me, DesignMode)
End Sub
Add a new form that inherits Form1 (Add form > Windows Forms > Inherited Form)

Rebuild.

Open a second Visual Studio instance without a project (click "Continue without code" in start screen) and click the "Run" button that now says "Attach..." (the option is also available in menu Debug > Attach to process...) and find the other devenv.exe that has your project open and attach to it. Display the Immediate Window. Now you have to find some arrangement so you can see output in Immediate Window while interacting with designer in other VS, for example use two monitors or maximize the attached VS and use window mode in project VS.

In open project do these experiments and observe debug messages in attached VS:
  • open and close Form1 in designer
  • add the MyTextBox to form, remove it again
  • add the MyTextBox to form, cut it and paste it again
  • add the UserControl1 to form, open and close the form in designer
  • open and close the inherited form in designer
You can also open the same project in second VS before attaching to first VS. In attached VS you can set breakpoints in code where debugger stops and you can inspect state when interacting with designer in other VS.
 

Great post. I'm sure I'll be playing with it for some time.

I'm been playing with the Debugs function a little.

Below is a sample of what I see.

Not sure what the top line means.

There are times when I change the code in VS1 and can not get VS2 to display the new code.

It does act as if it is using code from a cache rather than from the changed file.

I noticed Resize_Form can be DesignTime or DesignMode
Also for: Resize_UserControl

After I send this I'm going to try to find out more about that.


Thanks again. That post was extraordinary!


I noticed I did not get any hits below from FormClosing.

Client Verbose: 0 : Common model for csharp intellisense-members is cached.

Dispose_TextBox MyTextBox not_DesignMode/DesignTime

Dispose_TextBox MyTextBox not_DesignMode/DesignTime

Dispose_TextBox MyTextBox not_DesignMode/DesignTime

Disposed_Form Form1 not_DesignMode/DesignTime

Disposed_Form Form1 not_DesignMode/DesignTime

Disposed_Form Form1 not_DesignMode/DesignTime

Disposed_Form Form1 not_DesignMode/DesignTime

Disposed_TextBox MyTextBox not_DesignMode/DesignTime

Disposed_TextBox MyTextBox not_DesignMode/DesignTime

Disposed_UserControl UserControl1 not_DesignMode/DesignTime

Disposed_UserControl UserControl1 not_DesignMode/DesignTime

Disposed_UserControl UserControl1 not_DesignMode/DesignTime

Load_Form Form1 DesignMode

Load_Form Form1 DesignMode

Load_UserControl UserControl1 DesignMode

Load_UserControl UserControl1 DesignMode

Load_UserControl UserControl1 DesignMode

New_Form Form1 DesignTime

New_Form Form1 DesignTime

New_Form Form1 DesignTime

New_Form Form1 DesignTime

New_TextBox MyTextBox DesignTime

New_TextBox MyTextBox DesignTime

New_TextBox MyTextBox DesignTime

New_UserControl UserControl1 DesignTime

New_UserControl UserControl1 DesignTime

New_UserControl UserControl1 DesignTime

New_UserControl UserControl1 DesignTime

Resize_Form Form1 DesignTime

Resize_Form Form1 DesignMode

Resize_Form Form1 DesignTime

Resize_Form Form1 DesignMode

Resize_Form Form1 DesignTime

Resize_Form Form1 DesignMode

Resize_Form Form1 DesignTime

Resize_Form Form1 DesignMode

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignTime

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignMode

Resize_UserControl UserControl1 DesignMode
 
Last edited:
Question: Do you know of any reason why in my code I shouldn't siply always check
LicenseManager.UsageMode = LicenseUsageMode.Designtime
first and if it fails check DesignMode?
DesignMode is what I have used before, I'm not familiar with LicenseManager, it was just something I stumbled upon when checking DesignMode for constructor.
I also see disposing does not happen in designer, naturally since the object is removed from designer before that happens.
 
Probably wrongly, but I interpret

Disposed_UserControl UserControl1 not_DesignMode/DesignTime

as meaning the check is failing. I say this because I believe it was always in design mode while I was working with it. No?

That is, it seems to me, Disposed happens in design mode and the check should have said so.

I tried the following but it worked the same.


VB.NET:
  Public Sub Debugs(caller As Object, DesignMode As Boolean, <CallerMemberName> name As String)
        Dim base As String = caller.GetType.BaseType.Name
        If DesignMode Then
            Debug.WriteLine($"{name}_{base} {caller.GetType.Name} DesignMode")
        ElseIf LicenseManager.UsageMode = LicenseUsageMode.Designtime Then
            Debug.WriteLine($"{name}_{base} {caller.GetType.Name} DesignTime")
        Else
            Dim nextControl As Control = caller
            Dim site As ISite
            While nextControl IsNot Nothing
                site = nextControl.Site 'The first check is for the given control
                If site IsNot Nothing Then
                    If site.DesignMode Then
                        Debug.WriteLine($"{name}_{base} {caller.GetType.Name} While")
                        Exit Sub
                    End If
                End If
                nextControl = nextControl.Parent
            End While
            Debug.WriteLine($"{name}_{base} {caller.GetType.Name} Not_In_Designer")
        End If
    End Sub
.
 
No, your impression of "design mode" is not as it seems. "design mode" is when VS has the object active on its designer surface. As I said disposing happens after the object has been removed from designer. This happens when you remove a control, cut it (=temporary remove), close the designer view, and also when you rebuild as VS dispose all designed objects before recreating them.

You can also check Debugger.IsAttached, this doesn't mean the component is being designed, just that a debugger is currently attached to the process. Just like using VS to attach to other VS here to see designer related debug output you can also attach to any other running process for debugging purposes, and IsAttached would return true, still that doesn't mean anything in that process is being designed.
 
Back
Top