11 Replies Latest reply on Jul 30, 2012 4:45 PM by isbellj

    VB .NET Calling a Form

    gdebruin
      Hi,

      I'm in the process of converting code from VBA to VB. NET, and I'm having trouble calling a form I created from a button.
      Here's what I've tried so far:

      Protected Overrides Sub OnClick()

      Dim FormLogin As New System.Windows.Forms.Form
      FormLogin.Show()

      End Sub

      This brings up the form, but it's a completely blank form, which the form I'm attempting to call is not.
      Any help is appreciated.

      Thank you,
      cdebruin
        • Re: VB .NET Calling a Form
          ccposton
          Hi, 

          I'm in the process of converting code from VBA to VB. NET, and I'm having trouble calling a form I created from a button. 
          Here's what I've tried so far: 

          Protected Overrides Sub OnClick()

          Dim FormLogin As New System.Windows.Forms.Form
          FormLogin.Show()

          End Sub


          This brings up the form, but it's a completely blank form, which the form I'm attempting to call is not. 
          Any help is appreciated. 

          Thank you, 
          cdebruin


          rem What form were you trying to create?
          rem Dim FormLogin As New System.Windows.Forms.Form
          Dim FormLogin As New TheActualFormIAmTryingToCreateAndNotJustANonSpecificFormObject
          rem And how do I want the form to be displayed and handled 
          rem FormLogin.Show() ' A floating non-modal form that can be ignored
          FormLogin.ShowDialog() ' A modal form that requires the user to use it
          
          • Re: VB .NET Calling a Form
            EBejarano-esristaff
            Hi,

            In your VB.NET project you have defined a form class, e.g. myFormClass, that inherits or is derived from the System.Windows.Forms.Form class.  It is that form class that you have designed with various Windows Forms controls.  That is the class that you should be using when you declare your object variable FormLogin and that you set equal to a new instance of your myFormClass.  Instead you are creating an instance of the generic System.Windows.Forms.Form class.

            It should looks something like this in the .vb class file corresponding to your ArcMap or ArcCatalog custom button:

            Protected Overrides Sub OnClick()

            Dim FormLogin As New myFormClass
            FormLogin.Show()

            End Sub

            There should be a myFormClass.vb class file (the form class) in your VB.NET project when you do the above code, and that form class in turn should be inheriting from the System.Windows.Forms.Form class.
            • Re: VB .NET Calling a Form
              gdebruin
              Thank you!

              I see what you mean by creating instances of the generic windows form class as opposed to my own form.
              I fixed the code.

              Thanks again.
              • Re: VB .NET Calling a Form
                isbellj
                Now is there a way to set the Form.Owner property to be the ArcMap application? This would bring the form forward if the application window is made active.
                I found some documentation that shows how to do this with ArcGIS Explorer, which exposes a Application.Window reference that the Form.Owner property will accept.
                Unfortunately, the ArcMap Application class only exposes a hWnd integer. I have no clue what to do with that.

                Can anyone help?
                • Re: VB .NET Calling a Form
                  rlwatson
                  var parentWindow = new NEWindowsHandlerWrapper((IntPtr)_application.hWnd);

                      class NEWindowsHandlerWrapper : IWin32Window
                      {
                          private readonly IntPtr _handle;
                         
                          internal NEWindowsHandlerWrapper(IntPtr handle)
                          {
                              if(handle==IntPtr.Zero)
                              {
                                  throw new ArgumentOutOfRangeException("handle", "Handle cannot be empty.");
                              }
                              _handle = handle;
                          }

                          public IntPtr Handle
                          {
                              get { return _handle; }
                          }
                      }
                  • Re: VB .NET Calling a Form
                    isbellj
                    @rlwatson and @jtkknelson,
                    Thanks for the code and the links. I have it working now, thanks to helpful folks like you, here in these forums. Much appreciated!
                    -Jim
                    • Re: VB .NET Calling a Form
                      k_andras
                      isbellj,
                      Would you mind posting your code showing how you accomplished this?  I can't figure it out.
                      Thanks!!!
                      • Re: VB .NET Calling a Form
                        kenbuja
                        Here's an example for my VB.NET addin. In my project, I have created the class Win32HWNDWrapper and I have a form FieldInfoForm.

                        'this is the code in my main program to open the form
                        Dim FieldForm As New FieldInfoForm
                        FieldForm.ShowDialog(New Win32HWNDWrapper(My.ArcMap.Application.hWnd))
                        
                        'this is the code for the Win32HWNDWrapper class
                        Public Class Win32HWNDWrapper
                        
                            Implements System.Windows.Forms.IWin32Window
                            Private _hwnd As System.IntPtr
                        
                            Public ReadOnly Property Handle As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
                                Get
                                    Return _hwnd
                                End Get
                            End Property
                        
                            Public Sub New(ByVal Handle As System.IntPtr)
                                _hwnd = Handle
                            End Sub
                        
                        End Class
                        
                        • Re: VB .NET Calling a Form
                          isbellj
                          Thanks for that reply, @kenbuja. That's pretty much the same code I have, and it works beautifully.

                          Incidentally, I discovered that this technique can also be used with a System.Windows.Forms.MessageBox object. As you know (or will eventually find out), the default location for the MessageBox is at the CENTER OF YOUR DISPLAY SCREEN. This behavior is not what I prefer, so I use the Win32 Window Wrapper technique, as follows:

                          
                          Imports System.Windows.Forms
                          
                          
                          ' Example 1: This will open a MessageBox at the center of YOUR FORM:
                          MessageBox.Show(New Win32HWNDWrapper(MyFormInstanceName.Handle), "This is the message", "This is the caption")
                          
                          
                          ' Example 2: This will open a MessageBox at the center of the ARCMAP APPLICATION WINDOW:
                          MessageBox.Show(New Win32HWNDWrapper(My.ArcMap.Application.Hwnd), "This is the message", "This is the caption")

                          I hope someone finds this as useful as I have.
                          • Re: VB .NET Calling a Form
                            isbellj
                            Here's a follow-up to the Form Owner issue.

                            I saw this demonstrated at the 2012 User Conference in San Diego using only ONE LINE OF CODE! As it turns out, .NET has a built-in static method that can do the same thing as the wrapper class mentioned earlier. It works as follows:

                            MyFormInstanceName.Show(System.Windows.Forms.Control.FromHandle(My.ArcMap.Application.hWnd))

                            No wrapper class is needed after all!