Results 1 to 13 of 13

Thread: Stupid Questions, I Know... But I'm Stumped

  1. #1

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Stupid Questions, I Know... But I'm Stumped

    1) I've only been using VB.NET for a few days, doing a simple application for a friend. One thing has me stumped. I need to do some intialization *before* my form is first displayed. The obvious thing seemed to be to add a New method, and do it there. Trouble is, the New method NEVER get called! I've resorted to using one of the display event handlers to invoke an initialization method and set the flag indicating it's been done. In other words, a kludge. So why does my New method never get invoked? What SHOULD I be doing??

    2) To handle the resize events, I have a resize event handler to recalculate the sizes and positions of the controls. To do this, I need to know the design-time sizes. So, one of the things the initialization routine above does is save off enough information about the control sizes and positions to enable me to do this. There HAS to be a better way.... What is it?

    3) Is it just me, or is it truly brain-dead that doing the following:

    Dim X As Integer = 3
    Dim Y As Integer = X / 2

    sets Y to 2! I've never seen a language that treated integers in that way. Division should truncate, not round!

    Thanks!

    Regards,
    Ray L.

  2. #2
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Stupid Questions, I Know... But I'm Stumped

    1). Your New method does not get called? It should be... I have no idea why. Can you show us the code?
    On the other hand, you can initialize your code in the Form_Load event just fine. The form will only be shown when all the code in the Form_Load event is run, not right before it is run. Your form is not visible yet in the Form_Load event.


    2) The better way is using the Anchor and Dock properties of every control. Those allow you to determine how controls behave when the form is resized. Look them up, or play with them to find out what they do.


    3) Turn Option Strict On, please. X / 2 is not an Integer, it's a Double. If you turn Option Strict on, VB will error on your Dim Y As... line, telling you that "Option Strict On disallows implicit conversions from 'Double' to 'Integer'. This means that you explicitly have to convert the Double to an Integer, and in doing so, you can tell VB how to round, or truncate, the double (floating point) value.

    A few ways to do this:
    - Use integer division (\ instead of /)
    - Use the CInt function (only if you are certain that the argument you are passing is numeric)
    - Use the Integer.TryParse function (recommended, especially if you cannot guarantee that the argument is numeric)

    The CInt and integer division will fail if "x" is not numeric (like "92b"). The TryParse method will tell you (by returning False) that it could not convert "x" to an integer, and you can handle that gracefully instead of your application aborting.


    Quote Originally Posted by RayLivingston View Post
    Division should truncate, not round!
    No, it shouldn't. You are comparing apples to oranges. If I tell you to add 5 oranges and 3 apples, you wouldn't tell me I have 8 oranges, would you?
    What you are doing is called implicit conversion. You are basically telling VB to choose whichever conversion method it likes to use, because you don't care about the result. It is only 'kind' of VB to let you do this, but you should expect trouble if you do.

  3. #3

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Re: Stupid Questions, I Know... But I'm Stumped

    Quote Originally Posted by NickThissen View Post
    1). Your New method does not get called? It should be... I have no idea why. Can you show us the code?
    On the other hand, you can initialize your code in the Form_Load event just fine. The form will only be shown when all the code in the Form_Load event is run, not right before it is run. Your form is not visible yet in the Form_Load event.


    2) The better way is using the Anchor and Dock properties of every control. Those allow you to determine how controls behave when the form is resized. Look them up, or play with them to find out what they do.


    3) Turn Option Strict On, please. X / 2 is not an Integer, it's a Double. If you turn Option Strict on, VB will error on your Dim Y As... line, telling you that "Option Strict On disallows implicit conversions from 'Double' to 'Integer'. This means that you explicitly have to convert the Double to an Integer, and in doing so, you can tell VB how to round, or truncate, the double (floating point) value.

    A few ways to do this:
    - Use integer division (\ instead of /)
    - Use the CInt function (only if you are certain that the argument you are passing is numeric)
    - Use the Integer.TryParse function (recommended, especially if you cannot guarantee that the argument is numeric)

    The CInt and integer division will fail if "x" is not numeric (like "92b"). The TryParse method will tell you (by returning False) that it could not convert "x" to an integer, and you can handle that gracefully instead of your application aborting.



    No, it shouldn't. You are comparing apples to oranges. If I tell you to add 5 oranges and 3 apples, you wouldn't tell me I have 8 oranges, would you?
    What you are doing is called implicit conversion. You are basically telling VB to choose whichever conversion method it likes to use, because you don't care about the result. It is only 'kind' of VB to let you do this, but you should expect trouble if you do.
    Nick,

    Thanks for the quick response!

    1) My New is just the following, in the class for the main form:

    Public Sub New()

    ' This call is required by the Windows Form Designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

    ' My init code is here

    End Sub

    When I put a breakpoint anywhere in there, it never gets hit. Instead the Resize event handler seems to be the first thing that gets invoked.

    2) I will look at those. The reason I did what I did was my Googling led me to believe it was necessary. Obviously I didn't find the right sites! :-)

    3) Didn't realize there were two division operators! That makes sense. I would hope that Y = X \ 2 *would* give a result of 1?

    Regards,
    Ray L.

  4. #4

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Re: Stupid Questions, I Know... But I'm Stumped

    Nick,

    I tried Anchor and Dock, but those don't address the issue. I have a rectangular array of controls, all the same size and shape, and arranged in a regular order - think of a spreadsheet with all the cells the same size. When the form is resized, the sizes and location of all those controls need to be scaled, to maintain their size and position relative to the new window size. Currently, my init code stores away the design-time X,Y position of the top left control, the width and height of the top left control, the horizontal and vertical "pitch" of the controls, and the font size. With that information, I can use the scale factor provided in the resize event the calculate the new sizes, locations and font sizes of ALL the controls, and set them accordingly. My question was, is there a nicer way to do this, that doesn't require storing away that initialization information?

    There is no "Form_Load" even, but there is a "Load" event. I assume that's the one you mean. Funny thing is, this one does not get call until AFTER the first Resize event, which is why I grab my init information within the resize event. This seems to be the first event that occurs, which makes no sense to me...

    Thanks again!

    Regards,
    Ray L.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Stupid Questions, I Know... But I'm Stumped

    Are you using the default instance of the form? If you aren't sure what a default instance is, here's a brief, and possibly poor, explanation:

    When you create a form, you can give it a name, such as MyForm. That is actually the name of a class derived from Form with the name MyForm. However, beginning with 2005, .NET began adding default instances, which means that, while MyForm is the name of the class, .NET is also, quietly, making a global instance of type MyForm with the name MyForm. This creates havoc for people who are not familiar with it, because every other object has to be instantiated before it is used....except for forms. If you are using a default instance, it has to exist as soon as the program starts, so the constructor is called before the program actually starts. If you are doing something like this:

    Dim nf As New MyForm

    and you are working with nf, then the constructor WILL be called. After all, that InitializeComponent call is kind of vital. Without that, you won't have any controls on your form. However, if you are using the default instance, well, I believe you will get the behavior you are seeing.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Re: Stupid Questions, I Know... But I'm Stumped

    Quote Originally Posted by Shaggy Hiker View Post
    Are you using the default instance of the form? If you aren't sure what a default instance is, here's a brief, and possibly poor, explanation:

    When you create a form, you can give it a name, such as MyForm. That is actually the name of a class derived from Form with the name MyForm. However, beginning with 2005, .NET began adding default instances, which means that, while MyForm is the name of the class, .NET is also, quietly, making a global instance of type MyForm with the name MyForm. This creates havoc for people who are not familiar with it, because every other object has to be instantiated before it is used....except for forms. If you are using a default instance, it has to exist as soon as the program starts, so the constructor is called before the program actually starts. If you are doing something like this:

    Dim nf As New MyForm

    and you are working with nf, then the constructor WILL be called. After all, that InitializeComponent call is kind of vital. Without that, you won't have any controls on your form. However, if you are using the default instance, well, I believe you will get the behavior you are seeing.
    OK, that makes sense! Yes, I am using the default instance. However, last night when I added the constructor, I tried what you suggested, and it didn't *seem* to work, but I think I now understand why. Because the Resize event was occurring (on the default form) before the intialization call was made, it was throwing an exception. I can program around that, and I will try what you suggested, and let you know what happens.

    It's wonderful what you can do with these tools with very little effort, but all the stuff that happens "under the covers" can really get in the way sometimes....

    Thanks!

    Regards,
    Ray L.

  7. #7

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Re: Stupid Questions, I Know... But I'm Stumped

    Fascinating! I "if'd" the Resize event handler, so it does nothing if the init routine has not yet run, so the exception does not get thrown. NOW it makes it to the New method. So, Resize was being invoked BEFORE New()! How does that make sense?

    Regards,
    Ray L.

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Stupid Questions, I Know... But I'm Stumped

    It doesn't, unless you are working with the default instance. I really really hate the introduction of the default instance, and strongly suggest staying away from them. Not only is it hocus-pocus, but it behaves differently from ANY other object in the entire language, which causes nothing but confusion.

    I don't know how the default instance is created. I haven't played around with default instances to figure out what their limitations are.....because I hate them. I see no way to have a default instance if the constructor is converted to take an argument, for instance. Perhaps you don't have a default instance in that case. However, that call to InitializeComponents HAS to have run before anything else, or the controls simply don't exist. Re-size code wouldn't make any sense if the controls aren't in existence.
    My usual boring signature: Nothing

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Stupid Questions, I Know... But I'm Stumped

    Default instances do require a constructor with no parameters because that's what gets called when the default instance is created. By default, the designer-generated code contains a constructor that looks like so:
    vb.net Code:
    1. Public Sub New()
    2.     InitializeComponent()
    3. End Sub
    If you add a constructor to the user code file then that auto-generated constructor is removed. As such, if you add a constructor with parameters then it's up to you to add another constructor with no parameters if you want your form to have one. Whatever you do, the first thing your constructor must do is call InitializeComponent. If you have one constructor then it should be the first line. If you have multiple constructors then you'd normally do this:
    vb.net Code:
    1. Public Sub New()
    2.     InitializeComponent()
    3. End Sub
    4.  
    5. Public Sub New(ByVal obj As SomeType)
    6.     Me.New()
    7.  
    8.     'Use obj here.
    9. End Sub
    Now, when you invoke the parameter with the constructor, it will first invoke the parameterless constructor, which in turn calls InitializeComponent. If you do use the default instance then it will be created using the parameterless constructor and so no 'obj' will exist, meaning you'd have to pass it in using a property. Basically, default instances cause as many issues as they solve.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  10. #10

    Thread Starter
    New Member
    Join Date
    Jun 2009
    Posts
    6

    Re: Stupid Questions, I Know... But I'm Stumped

    Well this just continues to be bizarre. Now, in my Startup handler in ApplicationEvents, I create an explicit instance of my main form, and do a ShowDialog() on it. So far, so good. But when that form closes, the default instance of that form is displayed, even though I never explicity display it! How do you get around this, since the framework *requires* you to set one of the forms as the "main form"?

    I swear I've spent 30% of my time writing the actual application, the 70% trying to figure out goofy side-effects like this, and bugs in the SerialPort object....

    Regards,
    Ray L.

  11. #11
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Stupid Questions, I Know... But I'm Stumped

    That is simply not the way to do it so any goofy side-effects are likely to be of your own creation. What you should have done in the first place was simply pulled down the right-hand drop-down list at the top of the code window and clicked New. That would have created an appropriate constructor for you:
    vb.net Code:
    1. Public Sub New()
    2.  
    3.     ' This call is required by the Windows Form Designer.
    4.     InitializeComponent()
    5.  
    6.     ' Add any initialization after the InitializeComponent() call.
    7.  
    8. End Sub
    and removed the existing one from the designer code. You follow the instructions provided and put your initialisation code at the end of that constructor, after the InitializeComponent call where all your design time components are created and configured.

    That said, it's important to note that, if you set the Size to anything but the default in the designer, that's going to raise a Resize event and a SizeChanged event when your form is created. Those events are raised whenever the Size property changes and the InitializeComponent method is not special in that regard. If it changes a property value then the appropriate event(s) will be raised. If you want to know what Size of your form is when it's first displayed, the logical place to do that is in the Load event handler.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  12. #12
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Stupid Questions, I Know... But I'm Stumped

    Quote Originally Posted by RayLivingston View Post
    3) Didn't realize there were two division operators! That makes sense. I would hope that Y = X \ 2 *would* give a result of 1?
    I doubt it. I think it rounds, just like CInt does.

    If you want to decide whether to truncate or round it, then you should TELL it to. You can use the Math.Round function for example, and there's probably also a Math.Truncate function. You should never assume that VB does something if you are not telling it to. You should always tell it explicitly what to do.

  13. #13
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Stupid Questions, I Know... But I'm Stumped

    Quote Originally Posted by NickThissen View Post
    You should never assume that VB does something if you are not telling it to. You should always tell it explicitly what to do.
    Or maybe even read the documentation so you know for a fact that integer division does truncate.

    X = Y \ Z

    is equivalent to

    X = CInt(Math.Truncate(X / Z))

    Integer division is the complement to the Mod operator.

    X = Y / Z

    is equivalent to

    X = (Y \ Z) + (Y Mod Z)
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width