Refreshing a parent form

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MrFlabulous
    New Member
    • Feb 2012
    • 9

    Refreshing a parent form

    Hi,

    I'm a new programmer, and have a small problem. I've been trying to get a form populated with lots of buttons and tabs to be refreshed when its child form is closed. The routine I have is this:

    Code:
    NewForm_View show_it = new NewForm_View();
    show_it.ShowDialog();
    Form.ActiveForm.Refresh();
    If I understand correctly, the parent form code should pause until NewForm_View is Closed (or should it be Disposed?), and when it does it should be refreshed and the buttons updated - but it isn't. Do I need to run an Invoke routine?

    *edit: Just to be clear, the buttons are populated within the parent form's private void Parent_form_Loa d(object sender, EventArgs e) command.

    Hope you can help, many thanks, Howard Parker
    Last edited by MrFlabulous; Feb 13 '12, 09:59 AM. Reason: Clarity
  • GaryTexmo
    Recognized Expert Top Contributor
    • Jul 2009
    • 1501

    #2
    All the Refresh method does is invalidate the form it was called on. This triggers a new WM_PAINT event, which in turn causes the form to immediately redraw.

    If you're gathering information from a dialog and want to populate your main form with it, you will need to do that yourself. You can do that one of two ways... you can have the dialog form update the calling form itself, or you can simply update the calling form after you finish calling the dialog (likely preferable). For example, you might have this hypothetical situation...

    Code:
    // Inside a class called MainForm
    // Assuming a TextBox on the form called m_tbUserName
    private Hashtable m_userDB = new Hashtable();
    
    private void MainForm()
    {
      m_userDB.Add("admin", "12345");
    }
    
    private void LogInButton_Click(object sender, EventArgs e)
    {
      LoginForm loginForm = new LoginForm();
      if (loginForm.ShowDialog() != DialogResult.Ok)
      {
        MessageBox.Show("Login attempt was cancelled!");
        // Do whatever
      }
      else
      {
        if (m_userDB.ContainsKey(loginForm.UserName))
        {
          if (m_userDB[loginForm.UserName].ToString() == loginForm.Password)
          {
            m_tbUserName.Text = loginForm.UserName;
            MessageBox.Show(string.Format("Welcome, {0}!", loginForm.UserName), "Login Successful!");
            // Do whatever
          }
          else
          {
            MessageBox.Show("Password Incorrect!");
            // Do whatever
          }
        }
        else
        {
          MessageBox.Show("Unknown user!");
          // Do whatever.
        }
      }
    }
    Then you had a class called LoginForm that allowed you to input a user name and a password. You would then want the following bit of code in there...

    Code:
    // Assumes textboxes exist named m_tbUserName and m_tbPassword
    private string m_userName = "";
    private string m_password = "";
    
    public string UserName { get { return m_userName; } }
    public string Password { get { return m_password; } }
    
    public void LoginForm_FormClosing(...)
    {
      m_userName = m_tbUserName.Text;
      m_password = m_tbPassword.Text;
    }
    Note, it's important that you store the values of your dialog form's options in member variables and expose them with read only access in the FormClosing event. This is because when you close the dialog all the controls on it will dispose and you will be unable to access their values. This is why you couldn't simply do...

    Code:
    public String UserName { get { return m_tbUserName.Text; } }
    Hopefully that helps you out :)

    Comment

    • MrFlabulous
      New Member
      • Feb 2012
      • 9

      #3
      Hi, thanks. I'm not sure this is what I want, as I say I'm rather new to this and I don't want a messagebox particularly, I want the entire parent form to be refreshed, redrawn, reloaded, whatever it is.

      Basically, if the child form changes a parameter from "X" to "Y", when that child form is closed I want the parent to express that change directly, not via a messagebox. I have the code in place to have the parent filled properly when it's first loaded, I just don't know how to update it in realtime.

      Again, thanks, and I'm sorry if I'm being a bit vague and woolly.

      Howard

      Comment

      • GaryTexmo
        Recognized Expert Top Contributor
        • Jul 2009
        • 1501

        #4
        Those message boxes were just there for the example to do user feedback, and that example I made up completely. It has nothing to do with anything other than to show you how to access a property from a child form.

        In the code you originally posted, your opened your child form with the ShowDialog. This means your child form is modal; that is, you will be unable to interact with any other form until you address the modal form. Since you're calling it in this way, you know the method in which you called the child form is waiting for the child form to complete. So you can do a simple check on the return result from ShowDialog and then update your main form accordingly. See line 24 of the example...

        I've detected that the credentials are acceptable and the I update the text property of a control on the main form, a textbox with the name of m_tbUserName with the string value of my child form. Typically, your child form doesn't have access to the parent form. It only collects information and then the parent updates itself based on what was set on the child.

        Additionally, if you have code to update the parent properly when it's first loaded, can you not just call this after your child form returns?

        Anyway, give my example another look over and try to implement that code yourself in a sample project to see how it works. If it's still not what you're looking for and I'm not understanding you correctly (for which I apologize!) please post back with more of your own code so I can better get a feel for what you're trying to do.

        Comment

        • MrFlabulous
          New Member
          • Feb 2012
          • 9

          #5
          Hi Gary, thanks once again. I think I understand now, so I'll give this a try.

          Thanks for your time, I'll let you know how I get on.

          Howard

          Comment

          • MrFlabulous
            New Member
            • Feb 2012
            • 9

            #6
            Hi Gary, I've tried to re-run the populating routine separately but I've come up with another problem, still related. The issue may be due to drawing the form in visual c# then writing the code separately. The code I have starts out as:

            Code:
             private void ParentForm_Load(object sender, EventArgs e)
                    {
                        int ButtonCount = 0; // a counter, nothing more
                        Routines.BuildCurrentDatabase(); // Calls the data which will populate the Controls
                        foreach (Control cages in T7_Layout.Controls)
                        {
                            if (cages is Button)
                            { //text added, colours changed, etc
                            }
                        ButtonCount++
                   }
            The issue appears to be that I cannot put this code outside the ParentForm_Load () method. And since Refresh() will not work I cannot get the form to update once the child ShowDialog() has completed. I've changed it to Show() instead but still nothing. Can I physically run ParentForm_Load () again or should I close ParentForm and re-open it from another form?

            Sorry to be a pain, but this has been niggling me for some time now.

            Thanks

            Howard

            Comment

            • GaryTexmo
              Recognized Expert Top Contributor
              • Jul 2009
              • 1501

              #7
              I suppose you could call ParentForm_Load again, just give it a sender and new EventArgs. You could even give it a null sender since you don't appear to be using it...

              That said, you mentioned you can't put this code anywhere else? How did you do that... did you put it in another method or just copy/paste it? What errors did you get? You're going to need to provide more information before I can help you, sorry.

              Also, is this code a copy/paste from your program? There's two things I'm wondering about...
              1) I don't see a close brace for your foreach loop.
              2) You check to see if a control is a button and then do specific stuff, but you increment ButtonCount on every iteration of the foreach loop. Did you mean to have ButtonCount++ inside the if block?

              Finally, I don't see anything funny about this code outright... but things might be going wrong in your Routines.BuildC urrentDatabase call? Post some more details... more code might be helpful, as well as any errors that are generated when you call this code again.

              Comment

              • MrFlabulous
                New Member
                • Feb 2012
                • 9

                #8
                Hi, yeah, sorry it's abridged, just to give you a feel. Foreach is closed, and the counter is inside the block. Instead of tidying it up I've made it more confusing!

                So: By moving the code to a separate method I can only call it from ParentForm_Load () rather than another class, unless I make it a public static void method. And when I make it static, I get the message:

                Error 3 An object reference is required for the non-static field, method, or property 'dry_run_1.Pare ntForm.T7_Layou t' C:\Users\howpar \Documents\Visu al Studio 2010\Projects\d ry run 1\dry run 1\ParentForm.cs 392 39 dry run 1

                T7_Layout becomes inaccessible, but then if I remove the static command then the method isn't available anywhere else in the code. I guess I shoudl go with your suggestion of calling ParentForm_Load again.

                I think Routines.BuildC urrentDatabase is kosher, I've used it across several other forms and methods with no problems.

                Thanks

                Howard

                Comment

                • GaryTexmo
                  Recognized Expert Top Contributor
                  • Jul 2009
                  • 1501

                  #9
                  You could make it a public, non-static method, but here's a better question... why does any form except your main form need this? Your main form is the one triggering the dialog, right? It should just be able to update itself with the dialog information when the ShowDialog method returns.

                  Comment

                  • MrFlabulous
                    New Member
                    • Feb 2012
                    • 9

                    #10
                    Hi Gary - this makes more sense now, and (perhaps unsurprisingly) everything now works perfectly! Many, many thanks!

                    Howard

                    Comment

                    Working...