Memory corruption, problem closing multiple forms.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?UHVjY2E=?=

    Memory corruption, problem closing multiple forms.

    Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
    forms. I want allow users to move forward and backward with the forms and
    retain the data users have entered. I thought I'll make the inactive forms
    invisible but this is creating a memory corruption problem when user close
    the form2 or form3 and not the formMain.

    My main form has a Next button which makes the main form invisible and
    starts a new form which I'll call form2. The form 2 has a Previous and Next
    button. The previous button would make the main form visiable again. The
    next button would invoke a form3. both of these buttons would make form2
    invisible. The form3 has a previous button to go back to form2 vislble and
    make itself invisible. User can go forward and backward with these 3 forms.

    Actually, I have a boolean variable in formMain and form2 to indicate if
    form2 or form3 has been created. Since my application allows them to go back
    and forward with these 3 forms I only want to make form2 and form3 visible if
    they're already created.

    I already tried have code in the closing event of form2 and form3 to try to
    close it's calling form, namely form2 or formMain. But this doesn't work,
    you see, when my code sets the calling form to visible=false, it
    automatically callsing the form's Closing event. So, doesn't matter what
    code I put there, it will get executed when I'm just setting the form to be
    not visible.

    My question is, if the user is closing the application either at form2 or
    form3 then how do I make sure all forms are closed? Would coding to close
    the main form automatically close all the chidren form in the approperate
    order? If not, how can I address this? Becuase right now it's causing
    memory correuption in my application. Thanks.
    --
    Thanks.
  • Peter Duniho

    #2
    Re: Memory corruption, problem closing multiple forms.

    On Tue, 27 Mar 2007 23:16:03 -0700, Pucca
    <Pucca@discussi ons.microsoft.c omwrote:
    [...]
    My question is, if the user is closing the application either at form2 or
    form3 then how do I make sure all forms are closed? Would coding to
    close the main form automatically close all the chidren form in the
    approperate order? If not, how can I address this? Becuase right now
    it's causing memory correuption in my application. Thanks.
    Some thoughts:

    It's not clear from your post what "memory corruption" problem you're
    having. You mention having one, but other than that, there's nothing.

    I don't see how the visible/closing issue is related to the memory
    corruption issue. Memory corruption shouldn't happen in any case, no
    matter what you're doing with the forms, and there's not any reason that
    changing the visible property or closing a form should in and of itself
    corrupt memory.

    I also don't see why your Closing event gets fired when all you're doing
    is setting the Visible property to false. Hiding the form isn't the same
    as closing it, and it doesn't seem right that the Closing event would get
    fired (note that the converse is not necessarily true...for example, when
    a form is displayed as a modal dialog, clicking the close button on the
    form results in the form being hidden rather than actually disposed).

    Also note that as of .NET 2.0, you should use the FormClosing event,
    rather than the Closing event. For that matter, in your situation it
    seems to me that the Closed event is actually more appropriate. There's
    probably no practical difference, but it just seems like a better choice
    to me here, since at the point in time that the FormClosing event is
    received, it is not guaranteed that the form will actually be closed.

    Basically, there's a bit in your post that doesn't add up, at least at
    first read. If you could clarify your situation a bit, that would be
    helpful.

    Pete

    Comment

    • =?Utf-8?B?UGF0cmljayBTaW1wZS1Bc2FudGU=?=

      #3
      RE: Memory corruption, problem closing multiple forms.

      Hi ,

      I'm not sure whether design-wise what you have is the cleanest way to
      achieve what you're looking for - this might also explain why you're running
      into the kind of issues that you describe... I can suggest three other ways
      that might make coding this a little more straightforward :

      (1) A lightweight option could be to have one form, but with three separate
      groupBoxes that 'simulate' a form each, each groupBox of which contains the
      controls that you want to collect data in. Put a close, next and previous
      button on the form, and as the user clicks through next/previous, hide/unhide
      the groupBoxes. You could even create a sorted list populated with an enum
      code + groupBox, and cycle over to the first groupbox 'form' when the user
      clicks next past the third groupbox, or cycles backwards to the last groupbox
      'form' when the user clicks previous past the first entry.. This is the most
      simple to implement, however is probably the least amenable to change.

      As an example, your next/previous button click events might look something
      like (not compiled/tested):

      private void btnNext_Click(o bject sender, EventArgs e)
      {
      ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
      m_currentFormEn um++;
      if (m_currentFormE num == FormEnum.End)
      m_currentFormEn um = FormEnum.Form1;
      ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
      }

      private void btnPrevious_Cli ck(object sender, EventArgs e)
      {
      ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
      m_currentFormEn um--;
      if (m_currentFormE num == FormEnum.Begin)
      m_currentFormEn um = FormEnum.Form3;
      ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
      }


      (2) Another option, might be to represent each 'form' as a custom user
      control, which each contain the native .NET controls used to capture your
      required data. The user controls could have public properties that expose the
      data that the user entersin them. Again, a single form will host the three
      instantiated user controls, and you would have hide/unhide your custom user
      controls as the user clicks through next/previous. This is a little bit more
      work, however your new user controls will be re-useable elsewhere, and also
      would have a nice separation from the hosting Form (which is a good thing).

      (3) A third much more heavyweight option could be to use something like the
      User Interface Process Application Block from Microsoft which enables you to
      do what you're looking for, along with a whole lot more! You can find out
      about the UIPAB from:
      (1) http://msdn2.microsoft.com/en-us/library/ms979217.aspx
      (2) http://www.codeproject.com/dotnet/UIPAB1.asp

      Not sure why, but something tells me that there are many other possibilities
      as well ;-).. Hope this helps you though...

      Kind regards,
      Patrick
      --
      Patrick Simpe-Asante
      MCAD, MSCD.Net


      "Pucca" wrote:
      Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
      forms. I want allow users to move forward and backward with the forms and
      retain the data users have entered. I thought I'll make the inactive forms
      invisible but this is creating a memory corruption problem when user close
      the form2 or form3 and not the formMain.
      >
      My main form has a Next button which makes the main form invisible and
      starts a new form which I'll call form2. The form 2 has a Previous and Next
      button. The previous button would make the main form visiable again. The
      next button would invoke a form3. both of these buttons would make form2
      invisible. The form3 has a previous button to go back to form2 vislble and
      make itself invisible. User can go forward and backward with these 3 forms.
      >
      Actually, I have a boolean variable in formMain and form2 to indicate if
      form2 or form3 has been created. Since my application allows them to go back
      and forward with these 3 forms I only want to make form2 and form3 visible if
      they're already created.
      >
      I already tried have code in the closing event of form2 and form3 to try to
      close it's calling form, namely form2 or formMain. But this doesn't work,
      you see, when my code sets the calling form to visible=false, it
      automatically callsing the form's Closing event. So, doesn't matter what
      code I put there, it will get executed when I'm just setting the form to be
      not visible.
      >
      My question is, if the user is closing the application either at form2 or
      form3 then how do I make sure all forms are closed? Would coding to close
      the main form automatically close all the chidren form in the approperate
      order? If not, how can I address this? Becuase right now it's causing
      memory correuption in my application. Thanks.
      --
      Thanks.

      Comment

      • =?Utf-8?B?UGF0cmljayBTaW1wZS1Bc2FudGU=?=

        #4
        RE: Memory corruption, problem closing multiple forms.

        Hi Pucca,

        Forgot to mention - in the first option below, the group boxes would be
        overlaid over each other... Just in case that wasn't obvious from my post...

        regards,
        Patrick

        --
        Patrick Simpe-Asante
        MCAD, MSCD.Net


        "Patrick Simpe-Asante" wrote:
        Hi Pucca,
        >
        I'm not sure whether design-wise what you have is the cleanest way to
        achieve what you're looking for - this might also explain why you're running
        into the kind of issues that you describe... I can suggest three other ways
        that might make coding this a little more straightforward :
        >
        (1) A lightweight option could be to have one form, but with three separate
        groupBoxes that 'simulate' a form each, each groupBox of which contains the
        controls that you want to collect data in. Put a close, next and previous
        button on the form, and as the user clicks through next/previous, hide/unhide
        the groupBoxes. You could even create a sorted list populated with an enum
        code + groupBox, and cycle over to the first groupbox 'form' when the user
        clicks next past the third groupbox, or cycles backwards to the last groupbox
        'form' when the user clicks previous past the first entry.. This is the most
        simple to implement, however is probably the least amenable to change.
        >
        As an example, your next/previous button click events might look something
        like (not compiled/tested):
        >
        private void btnNext_Click(o bject sender, EventArgs e)
        {
        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
        m_currentFormEn um++;
        if (m_currentFormE num == FormEnum.End)
        m_currentFormEn um = FormEnum.Form1;
        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
        }
        >
        private void btnPrevious_Cli ck(object sender, EventArgs e)
        {
        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
        m_currentFormEn um--;
        if (m_currentFormE num == FormEnum.Begin)
        m_currentFormEn um = FormEnum.Form3;
        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
        }
        >
        >
        (2) Another option, might be to represent each 'form' as a custom user
        control, which each contain the native .NET controls used to capture your
        required data. The user controls could have public properties that expose the
        data that the user entersin them. Again, a single form will host the three
        instantiated user controls, and you would have hide/unhide your custom user
        controls as the user clicks through next/previous. This is a little bit more
        work, however your new user controls will be re-useable elsewhere, and also
        would have a nice separation from the hosting Form (which is a good thing).
        >
        (3) A third much more heavyweight option could be to use something like the
        User Interface Process Application Block from Microsoft which enables you to
        do what you're looking for, along with a whole lot more! You can find out
        about the UIPAB from:
        (1) http://msdn2.microsoft.com/en-us/library/ms979217.aspx
        (2) http://www.codeproject.com/dotnet/UIPAB1.asp
        >
        Not sure why, but something tells me that there are many other possibilities
        as well ;-).. Hope this helps you though...
        >
        Kind regards,
        Patrick
        --
        Patrick Simpe-Asante
        MCAD, MSCD.Net
        >
        >
        "Pucca" wrote:
        >
        Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
        forms. I want allow users to move forward and backward with the forms and
        retain the data users have entered. I thought I'll make the inactive forms
        invisible but this is creating a memory corruption problem when user close
        the form2 or form3 and not the formMain.

        My main form has a Next button which makes the main form invisible and
        starts a new form which I'll call form2. The form 2 has a Previous and Next
        button. The previous button would make the main form visiable again. The
        next button would invoke a form3. both of these buttons would make form2
        invisible. The form3 has a previous button to go back to form2 vislble and
        make itself invisible. User can go forward and backward with these 3 forms.

        Actually, I have a boolean variable in formMain and form2 to indicate if
        form2 or form3 has been created. Since my application allows them to go back
        and forward with these 3 forms I only want to make form2 and form3 visible if
        they're already created.

        I already tried have code in the closing event of form2 and form3 to try to
        close it's calling form, namely form2 or formMain. But this doesn't work,
        you see, when my code sets the calling form to visible=false, it
        automatically callsing the form's Closing event. So, doesn't matter what
        code I put there, it will get executed when I'm just setting the form to be
        not visible.

        My question is, if the user is closing the application either at form2 or
        form3 then how do I make sure all forms are closed? Would coding to close
        the main form automatically close all the chidren form in the approperate
        order? If not, how can I address this? Becuase right now it's causing
        memory correuption in my application. Thanks.
        --
        Thanks.

        Comment

        • =?Utf-8?B?UHVjY2E=?=

          #5
          Re: Memory corruption, problem closing multiple forms.

          The memory corruption occured when I close the application and had to click
          the stop button on VS and then trying to save changes to my code. I also
          notice there were a version of my appliation still running in the task
          manager and maybe that's why VS gave the memory corruption error when I tried
          to save.

          FormClosing event is the one I used. I was surprise to see in Debug that
          after setting visible property to false, the FormClosing was invoked. I used
          formName.ShowDl g(); initially to bring up form2 and form3 and then just set
          their visible property false to hide them. Could this be the reason that
          FormClosing is invoked?

          I willl go with Patrick's suggestion 1. That seems like a good solution.
          Thank you for all your input
          --
          Thanks.


          "Peter Duniho" wrote:
          On Tue, 27 Mar 2007 23:16:03 -0700, Pucca
          <Pucca@discussi ons.microsoft.c omwrote:
          >
          [...]
          My question is, if the user is closing the application either at form2 or
          form3 then how do I make sure all forms are closed? Would coding to
          close the main form automatically close all the chidren form in the
          approperate order? If not, how can I address this? Becuase right now
          it's causing memory correuption in my application. Thanks.
          >
          Some thoughts:
          >
          It's not clear from your post what "memory corruption" problem you're
          having. You mention having one, but other than that, there's nothing.
          >
          I don't see how the visible/closing issue is related to the memory
          corruption issue. Memory corruption shouldn't happen in any case, no
          matter what you're doing with the forms, and there's not any reason that
          changing the visible property or closing a form should in and of itself
          corrupt memory.
          >
          I also don't see why your Closing event gets fired when all you're doing
          is setting the Visible property to false. Hiding the form isn't the same
          as closing it, and it doesn't seem right that the Closing event would get
          fired (note that the converse is not necessarily true...for example, when
          a form is displayed as a modal dialog, clicking the close button on the
          form results in the form being hidden rather than actually disposed).
          >
          Also note that as of .NET 2.0, you should use the FormClosing event,
          rather than the Closing event. For that matter, in your situation it
          seems to me that the Closed event is actually more appropriate. There's
          probably no practical difference, but it just seems like a better choice
          to me here, since at the point in time that the FormClosing event is
          received, it is not guaranteed that the form will actually be closed.
          >
          Basically, there's a bit in your post that doesn't add up, at least at
          first read. If you could clarify your situation a bit, that would be
          helpful.
          >
          Pete
          >

          Comment

          • =?Utf-8?B?UHVjY2E=?=

            #6
            RE: Memory corruption, problem closing multiple forms.

            Hi Patrick, thank you for all the wonderful inupt. I think I willl be your
            1st solution. My appliation is a import tool so they don't just have groupbox
            on them. They have different controls and datagrids on each of the form. I
            think I will have the main on the designer and then create the form2 and
            form3 control upon loading of the formMain and hide them until they're
            needed. Do you think this will work and is a good solution? Also, if I make
            the control invisible, do I need to make them not able?
            --
            Thanks.


            "Patrick Simpe-Asante" wrote:
            Hi ,
            >
            I'm not sure whether design-wise what you have is the cleanest way to
            achieve what you're looking for - this might also explain why you're running
            into the kind of issues that you describe... I can suggest three other ways
            that might make coding this a little more straightforward :
            >
            (1) A lightweight option could be to have one form, but with three separate
            groupBoxes that 'simulate' a form each, each groupBox of which contains the
            controls that you want to collect data in. Put a close, next and previous
            button on the form, and as the user clicks through next/previous, hide/unhide
            the groupBoxes. You could even create a sorted list populated with an enum
            code + groupBox, and cycle over to the first groupbox 'form' when the user
            clicks next past the third groupbox, or cycles backwards to the last groupbox
            'form' when the user clicks previous past the first entry.. This is the most
            simple to implement, however is probably the least amenable to change.
            >
            As an example, your next/previous button click events might look something
            like (not compiled/tested):
            >
            private void btnNext_Click(o bject sender, EventArgs e)
            {
            ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
            m_currentFormEn um++;
            if (m_currentFormE num == FormEnum.End)
            m_currentFormEn um = FormEnum.Form1;
            ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
            }
            >
            private void btnPrevious_Cli ck(object sender, EventArgs e)
            {
            ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
            m_currentFormEn um--;
            if (m_currentFormE num == FormEnum.Begin)
            m_currentFormEn um = FormEnum.Form3;
            ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
            }
            >
            >
            (2) Another option, might be to represent each 'form' as a custom user
            control, which each contain the native .NET controls used to capture your
            required data. The user controls could have public properties that expose the
            data that the user entersin them. Again, a single form will host the three
            instantiated user controls, and you would have hide/unhide your custom user
            controls as the user clicks through next/previous. This is a little bit more
            work, however your new user controls will be re-useable elsewhere, and also
            would have a nice separation from the hosting Form (which is a good thing).
            >
            (3) A third much more heavyweight option could be to use something like the
            User Interface Process Application Block from Microsoft which enables you to
            do what you're looking for, along with a whole lot more! You can find out
            about the UIPAB from:
            (1) http://msdn2.microsoft.com/en-us/library/ms979217.aspx
            (2) http://www.codeproject.com/dotnet/UIPAB1.asp
            >
            Not sure why, but something tells me that there are many other possibilities
            as well ;-).. Hope this helps you though...
            >
            Kind regards,
            Patrick
            --
            Patrick Simpe-Asante
            MCAD, MSCD.Net
            >
            >
            "Pucca" wrote:
            >
            Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
            forms. I want allow users to move forward and backward with the forms and
            retain the data users have entered. I thought I'll make the inactive forms
            invisible but this is creating a memory corruption problem when user close
            the form2 or form3 and not the formMain.

            My main form has a Next button which makes the main form invisible and
            starts a new form which I'll call form2. The form 2 has a Previous and Next
            button. The previous button would make the main form visiable again. The
            next button would invoke a form3. both of these buttons would make form2
            invisible. The form3 has a previous button to go back to form2 vislble and
            make itself invisible. User can go forward and backward with these 3 forms.

            Actually, I have a boolean variable in formMain and form2 to indicate if
            form2 or form3 has been created. Since my application allows them to go back
            and forward with these 3 forms I only want to make form2 and form3 visible if
            they're already created.

            I already tried have code in the closing event of form2 and form3 to try to
            close it's calling form, namely form2 or formMain. But this doesn't work,
            you see, when my code sets the calling form to visible=false, it
            automatically callsing the form's Closing event. So, doesn't matter what
            code I put there, it will get executed when I'm just setting the form to be
            not visible.

            My question is, if the user is closing the application either at form2 or
            form3 then how do I make sure all forms are closed? Would coding to close
            the main form automatically close all the chidren form in the approperate
            order? If not, how can I address this? Becuase right now it's causing
            memory correuption in my application. Thanks.
            --
            Thanks.

            Comment

            • Peter Duniho

              #7
              Re: Memory corruption, problem closing multiple forms.

              On Wed, 28 Mar 2007 11:56:02 -0700, Pucca
              <Pucca@discussi ons.microsoft.c omwrote:
              The memory corruption occured when I close the application and had to
              click the stop button on VS and then trying to save changes to my code.
              I also notice there were a version of my appliation still running in the
              task manager and maybe that's why VS gave the memory corruption error
              when I tried to save.
              Ah. Well, then the problem is that you have to forcibly terminate your
              application.

              This is because the application only exits once all the forms have been
              closed. If you've simply hidden them, the application continues to run
              (unless it's forcibly terminated, of course).

              FormClosing event is the one I used. I was surprise to see in Debug that
              after setting visible property to false, the FormClosing was invoked. I
              used formName.ShowDl g(); initially to bring up form2 and form3 and then
              just set their visible property false to hide them. Could this be the
              reason that FormClosing is invoked?
              Could be. Have you tried just using the Show and Hide methods on the
              forms? I think that would be better than using ShowDialog (after all,
              they don't really sound like dialogs to me).
              I willl go with Patrick's suggestion 1. That seems like a good solution.
              Thank you for all your input
              I have found that layering different groups of controls on the same form
              makes it difficult to edit the form in the designer. However, if you
              don't find that to be a hassle then I'd agree that just keeping everything
              on the same form might make sense.

              Another option not mentioned is to implement each of your three forms as
              tabs on a single dialog. This would allow for an easier time designing,
              and provides the user with a familiar interface for switching from one
              form to the other.

              Of course, as you can see above, I don't think there's anything
              fundamentally wrong with the approach you tried first. It sounds as
              though you just need to learn a little more details about what actually
              happens when doing modeless vs modal, and closing vs hiding.

              Hope that helps...

              Pete

              Comment

              • =?Utf-8?B?UHVjY2E=?=

                #8
                Re: Memory corruption, problem closing multiple forms.

                Thanks Pete and Patrick for your great help. I have changed to use form.show
                and form.hide and these 2 working out fine without invoking the FormClosing
                event. I agree with you that layering controls on the same form does make it
                cumbersome to maintain and design. I would still like to have 3 forms if
                possible.

                I tried coding in the FormClosing event for all 3 forms so the the
                application can exit after all the forms are closed.
                1. if user click to close from formMain then if form2 was created,
                formMain's Fomclosing event would have: form2.close();
                2. In form2's FormClosing event: If form3 was created then form3.clsoe();

                The prblem is when user click to exit from form2 or form3. In form2
                FormClosing event besides form3.close();
                1. How does form2 inform formMain to close?
                2. Is that OK to do since formMain called form2?
                3. And how would I know in form2 the FormClosing is invoked by user
                clicking on form2's closing icon or invoked by formMain or form3?


                --
                Thanks.


                "Peter Duniho" wrote:
                On Wed, 28 Mar 2007 11:56:02 -0700, Pucca
                <Pucca@discussi ons.microsoft.c omwrote:
                >
                The memory corruption occured when I close the application and had to
                click the stop button on VS and then trying to save changes to my code.
                I also notice there were a version of my appliation still running in the
                task manager and maybe that's why VS gave the memory corruption error
                when I tried to save.
                >
                Ah. Well, then the problem is that you have to forcibly terminate your
                application.
                >
                This is because the application only exits once all the forms have been
                closed. If you've simply hidden them, the application continues to run
                (unless it's forcibly terminated, of course).
                >
                >
                FormClosing event is the one I used. I was surprise to see in Debug that
                after setting visible property to false, the FormClosing was invoked. I
                used formName.ShowDl g(); initially to bring up form2 and form3 and then
                just set their visible property false to hide them. Could this be the
                reason that FormClosing is invoked?
                >
                Could be. Have you tried just using the Show and Hide methods on the
                forms? I think that would be better than using ShowDialog (after all,
                they don't really sound like dialogs to me).
                >
                I willl go with Patrick's suggestion 1. That seems like a good solution.
                Thank you for all your input
                >
                I have found that layering different groups of controls on the same form
                makes it difficult to edit the form in the designer. However, if you
                don't find that to be a hassle then I'd agree that just keeping everything
                on the same form might make sense.
                >
                Another option not mentioned is to implement each of your three forms as
                tabs on a single dialog. This would allow for an easier time designing,
                and provides the user with a familiar interface for switching from one
                form to the other.
                >
                Of course, as you can see above, I don't think there's anything
                fundamentally wrong with the approach you tried first. It sounds as
                though you just need to learn a little more details about what actually
                happens when doing modeless vs modal, and closing vs hiding.
                >
                Hope that helps...
                >
                Pete
                >

                Comment

                • Peter Duniho

                  #9
                  Re: Memory corruption, problem closing multiple forms.

                  On Wed, 28 Mar 2007 16:26:02 -0700, Pucca
                  <Pucca@discussi ons.microsoft.c omwrote:
                  The prblem is when user click to exit from form2 or form3. In form2
                  FormClosing event besides form3.close();
                  1. How does form2 inform formMain to close?
                  Same way formMain "informs" form2 to close: formMain.Close( ).
                  2. Is that OK to do since formMain called form2?
                  Sure. The forms don't have a hierarchical relationship. They are all
                  peers in the same application. Just because formMain's code is what
                  caused form2 to be shown, that doesn't mean there's an ownership
                  relationship there. Any non-modal form can close any other form.
                  3. And how would I know in form2 the FormClosing is invoked by user
                  clicking on form2's closing icon or invoked by formMain or form3?
                  Well, the simplest solution is in each form to have a flag that notes
                  whether the form's FormClosing event has been signaled yet or not. The
                  FormClosing handler can be written to not do anything if that flag is set.

                  Basically, in each form the FormClosing handler can check that flag, and
                  if it's not set it would close the other two forms (checking to make sure
                  they have been insantiated first, of course) and set the flag. That way,
                  even if when the other forms get their FormClosing event and try to close
                  the form that started the whole process, if that form's FormClosing event
                  gets fired *again*, it won't do anything.

                  Actually, it is my recollection that when I did this, I didn't have any
                  trouble with recursive closing. I don't recall if that's because I used
                  the Closed event rather than the FormClosing event (IMHO, the Closed event
                  makes more sense), or if it's simply because when a form is closed, the
                  WM_CLOSE message is posted rather than sent directly. But either way, I
                  don't think there was a conflict the way I did it.

                  You can easily test this out yourself. The issue should be minor, and
                  easily addressed if necessary.

                  Pete

                  Comment

                  • =?Utf-8?B?UHVjY2E=?=

                    #10
                    Re: Memory corruption, problem closing multiple forms.

                    I put the code in the FormClosed event of 3 forms. It checks to see if
                    children forms were created then childForm.close (); is called. I pass the
                    calling form handle to both child forms, form2(this); which is receive as a
                    static Form variable in the child form.
                    I tried closing the form from form2 and the FormClosed was looped through
                    many times and then I get a error message: An unhandled exception of type
                    'System.stackov erflowexception ' occured in System.Windows. Forms.dll. Why
                    can't I close the calling form with the static form variable that stores the
                    calling form's handle? Also, the application stays in the task manager until
                    I exit the VS. Thank you.
                    --
                    Thanks.


                    "Peter Duniho" wrote:
                    On Wed, 28 Mar 2007 16:26:02 -0700, Pucca
                    <Pucca@discussi ons.microsoft.c omwrote:
                    >
                    The prblem is when user click to exit from form2 or form3. In form2
                    FormClosing event besides form3.close();
                    1. How does form2 inform formMain to close?
                    >
                    Same way formMain "informs" form2 to close: formMain.Close( ).
                    >
                    2. Is that OK to do since formMain called form2?
                    >
                    Sure. The forms don't have a hierarchical relationship. They are all
                    peers in the same application. Just because formMain's code is what
                    caused form2 to be shown, that doesn't mean there's an ownership
                    relationship there. Any non-modal form can close any other form.
                    >
                    3. And how would I know in form2 the FormClosing is invoked by user
                    clicking on form2's closing icon or invoked by formMain or form3?
                    >
                    Well, the simplest solution is in each form to have a flag that notes
                    whether the form's FormClosing event has been signaled yet or not. The
                    FormClosing handler can be written to not do anything if that flag is set.
                    >
                    Basically, in each form the FormClosing handler can check that flag, and
                    if it's not set it would close the other two forms (checking to make sure
                    they have been insantiated first, of course) and set the flag. That way,
                    even if when the other forms get their FormClosing event and try to close
                    the form that started the whole process, if that form's FormClosing event
                    gets fired *again*, it won't do anything.
                    >
                    Actually, it is my recollection that when I did this, I didn't have any
                    trouble with recursive closing. I don't recall if that's because I used
                    the Closed event rather than the FormClosing event (IMHO, the Closed event
                    makes more sense), or if it's simply because when a form is closed, the
                    WM_CLOSE message is posted rather than sent directly. But either way, I
                    don't think there was a conflict the way I did it.
                    >
                    You can easily test this out yourself. The issue should be minor, and
                    easily addressed if necessary.
                    >
                    Pete
                    >

                    Comment

                    • Peter Duniho

                      #11
                      Re: Memory corruption, problem closing multiple forms.

                      On Wed, 28 Mar 2007 18:58:03 -0700, Pucca
                      <Pucca@discussi ons.microsoft.c omwrote:
                      [...]
                      I tried closing the form from form2 and the FormClosed was looped through
                      many times and then I get a error message: An unhandled exception of type
                      'System.stackov erflowexception ' occured in System.Windows. Forms.dll. Why
                      can't I close the calling form with the static form variable that stores
                      the calling form's handle?
                      You have an unterminated recursion, thus the stack overflow. I would
                      guess that your two forms are busy trying to close each other. One tries
                      to close the other, which then tries to close the first, which causes the
                      first to again try to close the other, and so on.

                      My previous post includes suggestions for how to work around just such a
                      problem. Have you tried any of those suggestions?
                      Also, the application stays in the task manager until I exit the VS.
                      Thank you.
                      As I mentioned, your application won't exit until all forms are closed
                      (and until all non-background threads have terminated, though you have not
                      made any mention of any other threads, so I assume that's not your
                      problem).

                      Also, you are still using this "child form" terminology. I recommend you
                      stop thinking of the forms as being children of other forms. There's no
                      such hierarchy for the non-modal forms, and I believe that treating them
                      as though there is may lead to conceptual misunderstandin gs that either
                      prevent you from solving problems, or cause bugs, or both.

                      Also, I don't understand the use of a static variable to keep track of a
                      form. I don't think it's necessary to keep track of any form (after all,
                      all of your forms should already have references within the namespace that
                      you can use directly), but assuming you feel it necessary to store a
                      reference in a variable upon creation of a form, that value should be
                      stored as a normal member within the instance of the created form.

                      Pete

                      Comment

                      • =?Utf-8?B?UGF0cmljayBTaW1wZS1Bc2FudGU=?=

                        #12
                        RE: Memory corruption, problem closing multiple forms.

                        Hi Pucca,

                        Yes the first solution is probably the simplest..

                        The reason I suggested use of group boxes that contain your data controls is
                        that rather than having to individually hide each control as the user clicks
                        next/previous (you would end up with a lot of similar-looking code), you can
                        simply hide the group box and all the contained data controls will be hidden
                        as well. For example if your GroupBox 1, representing your first form
                        contained 15 controls, you could set those 15 controls visible property to
                        true. When you hide the GroupBox, all the contained controls will also be
                        hidden in spite of the fact that you set the controls visible property to
                        true. The GroupBox is a special kind of control that has the ability to
                        'contain' other controls, and certain properties when set on teh container
                        will ripple down to the contained - one other option you might want to look
                        at is the "Panel" class which can also be used to to contain data controls
                        (the Panel container might even be a better option than the group box).

                        If you use either the group box or panel to contain your controls and design
                        them using the VS.NET forms designer, you will not need to 'create' forms at
                        runtime which is where problems seem to have been occurring..

                        "Also, if I make the control invisible, do I need to make them not able? "
                        <-- I'm not sure I understand this last question - did you mean editable? If
                        so, making a control invisible, does not require setting them to be
                        non-editable as by definition they are not visible for the user to perform
                        any kind of input...

                        Hope this helps..

                        Kind regards,
                        Patrick
                        --
                        Patrick Simpe-Asante
                        MCAD, MSCD.Net


                        "Pucca" wrote:
                        Hi Patrick, thank you for all the wonderful inupt. I think I willl be your
                        1st solution. My appliation is a import tool so they don't just have groupbox
                        on them. They have different controls and datagrids on each of the form. I
                        think I will have the main on the designer and then create the form2 and
                        form3 control upon loading of the formMain and hide them until they're
                        needed. Do you think this will work and is a good solution? Also, if I make
                        the control invisible, do I need to make them not able?
                        --
                        Thanks.
                        >
                        >
                        "Patrick Simpe-Asante" wrote:
                        >
                        Hi ,

                        I'm not sure whether design-wise what you have is the cleanest way to
                        achieve what you're looking for - this might also explain why you're running
                        into the kind of issues that you describe... I can suggest three other ways
                        that might make coding this a little more straightforward :

                        (1) A lightweight option could be to have one form, but with three separate
                        groupBoxes that 'simulate' a form each, each groupBox of which contains the
                        controls that you want to collect data in. Put a close, next and previous
                        button on the form, and as the user clicks through next/previous, hide/unhide
                        the groupBoxes. You could even create a sorted list populated with an enum
                        code + groupBox, and cycle over to the first groupbox 'form' when the user
                        clicks next past the third groupbox, or cycles backwards to the last groupbox
                        'form' when the user clicks previous past the first entry.. This is the most
                        simple to implement, however is probably the least amenable to change.

                        As an example, your next/previous button click events might look something
                        like (not compiled/tested):

                        private void btnNext_Click(o bject sender, EventArgs e)
                        {
                        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
                        m_currentFormEn um++;
                        if (m_currentFormE num == FormEnum.End)
                        m_currentFormEn um = FormEnum.Form1;
                        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
                        }

                        private void btnPrevious_Cli ck(object sender, EventArgs e)
                        {
                        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
                        m_currentFormEn um--;
                        if (m_currentFormE num == FormEnum.Begin)
                        m_currentFormEn um = FormEnum.Form3;
                        ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
                        }


                        (2) Another option, might be to represent each 'form' as a custom user
                        control, which each contain the native .NET controls used to capture your
                        required data. The user controls could have public properties that expose the
                        data that the user entersin them. Again, a single form will host the three
                        instantiated user controls, and you would have hide/unhide your custom user
                        controls as the user clicks through next/previous. This is a little bit more
                        work, however your new user controls will be re-useable elsewhere, and also
                        would have a nice separation from the hosting Form (which is a good thing).

                        (3) A third much more heavyweight option could be to use something like the
                        User Interface Process Application Block from Microsoft which enables you to
                        do what you're looking for, along with a whole lot more! You can find out
                        about the UIPAB from:
                        (1) http://msdn2.microsoft.com/en-us/library/ms979217.aspx
                        (2) http://www.codeproject.com/dotnet/UIPAB1.asp

                        Not sure why, but something tells me that there are many other possibilities
                        as well ;-).. Hope this helps you though...

                        Kind regards,
                        Patrick
                        --
                        Patrick Simpe-Asante
                        MCAD, MSCD.Net


                        "Pucca" wrote:
                        Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
                        forms. I want allow users to move forward and backward with the forms and
                        retain the data users have entered. I thought I'll make the inactive forms
                        invisible but this is creating a memory corruption problem when user close
                        the form2 or form3 and not the formMain.
                        >
                        My main form has a Next button which makes the main form invisible and
                        starts a new form which I'll call form2. The form 2 has a Previous and Next
                        button. The previous button would make the main form visiable again. The
                        next button would invoke a form3. both of these buttons would make form2
                        invisible. The form3 has a previous button to go back to form2 vislble and
                        make itself invisible. User can go forward and backward with these 3 forms.
                        >
                        Actually, I have a boolean variable in formMain and form2 to indicate if
                        form2 or form3 has been created. Since my application allows them to go back
                        and forward with these 3 forms I only want to make form2 and form3 visible if
                        they're already created.
                        >
                        I already tried have code in the closing event of form2 and form3 to try to
                        close it's calling form, namely form2 or formMain. But this doesn't work,
                        you see, when my code sets the calling form to visible=false, it
                        automatically callsing the form's Closing event. So, doesn't matter what
                        code I put there, it will get executed when I'm just setting the form to be
                        not visible.
                        >
                        My question is, if the user is closing the application either at form2 or
                        form3 then how do I make sure all forms are closed? Would coding to close
                        the main form automatically close all the chidren form in the approperate
                        order? If not, how can I address this? Becuase right now it's causing
                        memory correuption in my application. Thanks.
                        --
                        Thanks.

                        Comment

                        • =?Utf-8?B?UHVjY2E=?=

                          #13
                          Re: Memory corruption, problem closing multiple forms.

                          Hi Peter, I forgot to add the flag for the closed event. It is now working
                          when close from form2 or form3. Thank you for all your help through this
                          very confusing issue for me. I really appreciate it.
                          --
                          Thanks.


                          "Peter Duniho" wrote:
                          On Wed, 28 Mar 2007 16:26:02 -0700, Pucca
                          <Pucca@discussi ons.microsoft.c omwrote:
                          >
                          The prblem is when user click to exit from form2 or form3. In form2
                          FormClosing event besides form3.close();
                          1. How does form2 inform formMain to close?
                          >
                          Same way formMain "informs" form2 to close: formMain.Close( ).
                          >
                          2. Is that OK to do since formMain called form2?
                          >
                          Sure. The forms don't have a hierarchical relationship. They are all
                          peers in the same application. Just because formMain's code is what
                          caused form2 to be shown, that doesn't mean there's an ownership
                          relationship there. Any non-modal form can close any other form.
                          >
                          3. And how would I know in form2 the FormClosing is invoked by user
                          clicking on form2's closing icon or invoked by formMain or form3?
                          >
                          Well, the simplest solution is in each form to have a flag that notes
                          whether the form's FormClosing event has been signaled yet or not. The
                          FormClosing handler can be written to not do anything if that flag is set.
                          >
                          Basically, in each form the FormClosing handler can check that flag, and
                          if it's not set it would close the other two forms (checking to make sure
                          they have been insantiated first, of course) and set the flag. That way,
                          even if when the other forms get their FormClosing event and try to close
                          the form that started the whole process, if that form's FormClosing event
                          gets fired *again*, it won't do anything.
                          >
                          Actually, it is my recollection that when I did this, I didn't have any
                          trouble with recursive closing. I don't recall if that's because I used
                          the Closed event rather than the FormClosing event (IMHO, the Closed event
                          makes more sense), or if it's simply because when a form is closed, the
                          WM_CLOSE message is posted rather than sent directly. But either way, I
                          don't think there was a conflict the way I did it.
                          >
                          You can easily test this out yourself. The issue should be minor, and
                          easily addressed if necessary.
                          >
                          Pete
                          >

                          Comment

                          • Peter Duniho

                            #14
                            Re: Memory corruption, problem closing multiple forms.

                            On Thu, 29 Mar 2007 10:30:02 -0700, Pucca
                            <Pucca@discussi ons.microsoft.c omwrote:
                            Hi Peter, I forgot to add the flag for the closed event. It is now
                            working when close from form2 or form3. Thank you for all your help
                            through this very confusing issue for me. I really appreciate it.
                            You're welcome. I'm glad everything worked out. :)


                            Comment

                            • =?Utf-8?B?UHVjY2E=?=

                              #15
                              RE: Memory corruption, problem closing multiple forms.

                              Thank you very much for all your great input. I've learned a lot from both
                              you and Peter.
                              --
                              Thanks.


                              "Patrick Simpe-Asante" wrote:
                              Hi Pucca,
                              >
                              Yes the first solution is probably the simplest..
                              >
                              The reason I suggested use of group boxes that contain your data controls is
                              that rather than having to individually hide each control as the user clicks
                              next/previous (you would end up with a lot of similar-looking code), you can
                              simply hide the group box and all the contained data controls will be hidden
                              as well. For example if your GroupBox 1, representing your first form
                              contained 15 controls, you could set those 15 controls visible property to
                              true. When you hide the GroupBox, all the contained controls will also be
                              hidden in spite of the fact that you set the controls visible property to
                              true. The GroupBox is a special kind of control that has the ability to
                              'contain' other controls, and certain properties when set on teh container
                              will ripple down to the contained - one other option you might want to look
                              at is the "Panel" class which can also be used to to contain data controls
                              (the Panel container might even be a better option than the group box).
                              >
                              If you use either the group box or panel to contain your controls and design
                              them using the VS.NET forms designer, you will not need to 'create' forms at
                              runtime which is where problems seem to have been occurring..
                              >
                              "Also, if I make the control invisible, do I need to make them not able? "
                              <-- I'm not sure I understand this last question - did you mean editable? If
                              so, making a control invisible, does not require setting them to be
                              non-editable as by definition they are not visible for the user to perform
                              any kind of input...
                              >
                              Hope this helps..
                              >
                              Kind regards,
                              Patrick
                              --
                              Patrick Simpe-Asante
                              MCAD, MSCD.Net
                              >
                              >
                              "Pucca" wrote:
                              >
                              Hi Patrick, thank you for all the wonderful inupt. I think I willl be your
                              1st solution. My appliation is a import tool so they don't just have groupbox
                              on them. They have different controls and datagrids on each of the form. I
                              think I will have the main on the designer and then create the form2 and
                              form3 control upon loading of the formMain and hide them until they're
                              needed. Do you think this will work and is a good solution? Also, if I make
                              the control invisible, do I need to make them not able?
                              --
                              Thanks.


                              "Patrick Simpe-Asante" wrote:
                              Hi ,
                              >
                              I'm not sure whether design-wise what you have is the cleanest way to
                              achieve what you're looking for - this might also explain why you're running
                              into the kind of issues that you describe... I can suggest three other ways
                              that might make coding this a little more straightforward :
                              >
                              (1) A lightweight option could be to have one form, but with three separate
                              groupBoxes that 'simulate' a form each, each groupBox of which contains the
                              controls that you want to collect data in. Put a close, next and previous
                              button on the form, and as the user clicks through next/previous, hide/unhide
                              the groupBoxes. You could even create a sorted list populated with an enum
                              code + groupBox, and cycle over to the first groupbox 'form' when the user
                              clicks next past the third groupbox, or cycles backwards to the last groupbox
                              'form' when the user clicks previous past the first entry.. This is the most
                              simple to implement, however is probably the least amenable to change.
                              >
                              As an example, your next/previous button click events might look something
                              like (not compiled/tested):
                              >
                              private void btnNext_Click(o bject sender, EventArgs e)
                              {
                              ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
                              m_currentFormEn um++;
                              if (m_currentFormE num == FormEnum.End)
                              m_currentFormEn um = FormEnum.Form1;
                              ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
                              }
                              >
                              private void btnPrevious_Cli ck(object sender, EventArgs e)
                              {
                              ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = false;
                              m_currentFormEn um--;
                              if (m_currentFormE num == FormEnum.Begin)
                              m_currentFormEn um = FormEnum.Form3;
                              ((GroupBox)(m_g roupBoxList[m_currentFormEn um])).Visible = true;
                              }
                              >
                              >
                              (2) Another option, might be to represent each 'form' as a custom user
                              control, which each contain the native .NET controls used to capture your
                              required data. The user controls could have public properties that expose the
                              data that the user entersin them. Again, a single form will host the three
                              instantiated user controls, and you would have hide/unhide your custom user
                              controls as the user clicks through next/previous. This is a little bit more
                              work, however your new user controls will be re-useable elsewhere, and also
                              would have a nice separation from the hosting Form (which is a good thing).
                              >
                              (3) A third much more heavyweight option could be to use something like the
                              User Interface Process Application Block from Microsoft which enables you to
                              do what you're looking for, along with a whole lot more! You can find out
                              about the UIPAB from:
                              (1) http://msdn2.microsoft.com/en-us/library/ms979217.aspx
                              (2) http://www.codeproject.com/dotnet/UIPAB1.asp
                              >
                              Not sure why, but something tells me that there are many other possibilities
                              as well ;-).. Hope this helps you though...
                              >
                              Kind regards,
                              Patrick
                              --
                              Patrick Simpe-Asante
                              MCAD, MSCD.Net
                              >
                              >
                              "Pucca" wrote:
                              >
                              Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3
                              forms. I want allow users to move forward and backward with the forms and
                              retain the data users have entered. I thought I'll make the inactive forms
                              invisible but this is creating a memory corruption problem when user close
                              the form2 or form3 and not the formMain.

                              My main form has a Next button which makes the main form invisible and
                              starts a new form which I'll call form2. The form 2 has a Previous and Next
                              button. The previous button would make the main form visiable again. The
                              next button would invoke a form3. both of these buttons would make form2
                              invisible. The form3 has a previous button to go back to form2 vislble and
                              make itself invisible. User can go forward and backward with these 3 forms.

                              Actually, I have a boolean variable in formMain and form2 to indicate if
                              form2 or form3 has been created. Since my application allows them to go back
                              and forward with these 3 forms I only want to make form2 and form3 visible if
                              they're already created.

                              I already tried have code in the closing event of form2 and form3 to try to
                              close it's calling form, namely form2 or formMain. But this doesn't work,
                              you see, when my code sets the calling form to visible=false, it
                              automatically callsing the form's Closing event. So, doesn't matter what
                              code I put there, it will get executed when I'm just setting the form to be
                              not visible.

                              My question is, if the user is closing the application either at form2 or
                              form3 then how do I make sure all forms are closed? Would coding to close
                              the main form automatically close all the chidren form in the approperate
                              order? If not, how can I address this? Becuase right now it's causing
                              memory correuption in my application. Thanks.
                              --
                              Thanks.

                              Comment

                              Working...