Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Accessing mdiParent form menu from mdiChild form via code [solved]

Accessing mdiParent form menu from mdiChild form via code [solved]

Scheduled Pinned Locked Moved C#
questionhelp
12 Posts 4 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AussieLew
    wrote on last edited by
    #1

    I have a start up form call MainForm called as follows...

    static void Main()
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
    }

    On MainForm I have a MenuStrip with MenuItems and ToolStripMenuItems. Some of these ToolStripMenuItems have a property of CheckOnClick set to True. From MainForm I open another form called f1 based on HormoneTypeForm, as an MDI child...

    private void hormoneTypeToolStripMenuItem_Click(object sender, EventArgs e)
    {
    HormoneTypeForm f1 = new HormoneTypeForm();
    f1.MdiParent = this;
    hormoneTypeToolStripMenuItem.Enabled = false;
    f1.Show();
    }

    My question is - From form f1 how do I get ( or set ) the Checked value of some of the ToolStripMenuItems on the MainForm menu? What I want to do in form f1 is take actions conditional on the Checked value of some ToolStripMenuItems on the main form MainForm (MdiParent). I cannot find anyway to reference the MainForm ToolStripMenuItems properties from form f1. I'm sure it simple but.....? Thanks for any help.

    modified on Saturday, July 31, 2010 4:51 AM

    L D 2 Replies Last reply
    0
    • A AussieLew

      I have a start up form call MainForm called as follows...

      static void Main()
      {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new MainForm());
      }

      On MainForm I have a MenuStrip with MenuItems and ToolStripMenuItems. Some of these ToolStripMenuItems have a property of CheckOnClick set to True. From MainForm I open another form called f1 based on HormoneTypeForm, as an MDI child...

      private void hormoneTypeToolStripMenuItem_Click(object sender, EventArgs e)
      {
      HormoneTypeForm f1 = new HormoneTypeForm();
      f1.MdiParent = this;
      hormoneTypeToolStripMenuItem.Enabled = false;
      f1.Show();
      }

      My question is - From form f1 how do I get ( or set ) the Checked value of some of the ToolStripMenuItems on the MainForm menu? What I want to do in form f1 is take actions conditional on the Checked value of some ToolStripMenuItems on the main form MainForm (MdiParent). I cannot find anyway to reference the MainForm ToolStripMenuItems properties from form f1. I'm sure it simple but.....? Thanks for any help.

      modified on Saturday, July 31, 2010 4:51 AM

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      You can made one function on mainform which will return the value of ToolStripMenuItem. And before showing the form f1 assign the value of it to some variable to f1 as follows.

      f1.Somevariable=this.Returnvalueoftoolstripmenuitem();
      f1.Show();

      That's it. HTH

      Jinal Desai - LIVE Experience is mother of sage....

      A D 2 Replies Last reply
      0
      • L Lost User

        You can made one function on mainform which will return the value of ToolStripMenuItem. And before showing the form f1 assign the value of it to some variable to f1 as follows.

        f1.Somevariable=this.Returnvalueoftoolstripmenuitem();
        f1.Show();

        That's it. HTH

        Jinal Desai - LIVE Experience is mother of sage....

        A Offline
        A Offline
        AussieLew
        wrote on last edited by
        #3

        Thanks, the problem with that ( I think ) is that the value of the ToolStripMenuItem could be changed subsequently by another open MdiChild form. One way that I can get half of what I need is to have a public static variable in a static class ( say my starting code ) which I can access from all of my forms. I can then set the value of this to the value of the ToolStripMenuItem.Checked property in the CheckedChanged event handler for the ToolStripMenuItem. I can then check ToolStripMenuItem.Checked for a certain condition from any child form. But.... how can I Set the ToolStripMenuItem.Checked property in code? It may help if I give a better example of what I want to do. In MainForm ( the MdiParent form ) I have a confirmDeletesToolStripMenuItem with CheckOnClick set to True. In any child form, during the delete process, if MainForm confirmDeletesToolStripMenuItem.Checked == True; then they will get a Confirm Deletes Message Box or not if False. In the Confirm Deletes Message Box I will also have a CheckBox option "Do not show again for this session" that if checked will Set the MainForm confirmDeletesToolStripMenuItem.Checked = False;. I guess I can also use Application Settings and set this type of thing in an Options form rather than on a Checked ToolStripMenuItem, however I'm sure there will be other reasons Get/Set the value of the Parent form from Child?

        L 1 Reply Last reply
        0
        • A AussieLew

          Thanks, the problem with that ( I think ) is that the value of the ToolStripMenuItem could be changed subsequently by another open MdiChild form. One way that I can get half of what I need is to have a public static variable in a static class ( say my starting code ) which I can access from all of my forms. I can then set the value of this to the value of the ToolStripMenuItem.Checked property in the CheckedChanged event handler for the ToolStripMenuItem. I can then check ToolStripMenuItem.Checked for a certain condition from any child form. But.... how can I Set the ToolStripMenuItem.Checked property in code? It may help if I give a better example of what I want to do. In MainForm ( the MdiParent form ) I have a confirmDeletesToolStripMenuItem with CheckOnClick set to True. In any child form, during the delete process, if MainForm confirmDeletesToolStripMenuItem.Checked == True; then they will get a Confirm Deletes Message Box or not if False. In the Confirm Deletes Message Box I will also have a CheckBox option "Do not show again for this session" that if checked will Set the MainForm confirmDeletesToolStripMenuItem.Checked = False;. I guess I can also use Application Settings and set this type of thing in an Options form rather than on a Checked ToolStripMenuItem, however I'm sure there will be other reasons Get/Set the value of the Parent form from Child?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Along with storing checked status in configuration file there are other options also available, like.. Make one class and in that define one property which holds the value of ToolStripMenuItem, and pass the object of this class between the forms(mdi and child form) whenever you required the value of ToolStripMenuItem. And also you need to update the value of the class property whenever the change occurs in value of ToolStripMenuItem. HTH

          Jinal Desai - LIVE Experience is mother of sage....

          1 Reply Last reply
          0
          • A AussieLew

            I have a start up form call MainForm called as follows...

            static void Main()
            {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
            }

            On MainForm I have a MenuStrip with MenuItems and ToolStripMenuItems. Some of these ToolStripMenuItems have a property of CheckOnClick set to True. From MainForm I open another form called f1 based on HormoneTypeForm, as an MDI child...

            private void hormoneTypeToolStripMenuItem_Click(object sender, EventArgs e)
            {
            HormoneTypeForm f1 = new HormoneTypeForm();
            f1.MdiParent = this;
            hormoneTypeToolStripMenuItem.Enabled = false;
            f1.Show();
            }

            My question is - From form f1 how do I get ( or set ) the Checked value of some of the ToolStripMenuItems on the MainForm menu? What I want to do in form f1 is take actions conditional on the Checked value of some ToolStripMenuItems on the main form MainForm (MdiParent). I cannot find anyway to reference the MainForm ToolStripMenuItems properties from form f1. I'm sure it simple but.....? Thanks for any help.

            modified on Saturday, July 31, 2010 4:51 AM

            D Offline
            D Offline
            DaveyM69
            wrote on last edited by
            #5

            I would do it in a slightly long winded way, but it's far more flexible/extendable in future. All child forms that need this functionality should raise an event to signal to the parent that it wants to update it's menu. The children should never have access to the menu directly! The best way to do this is to have a enumeration of menu items that you can add to as required.

            // UpdatableMenuItem.cs

            namespace YourMdiApp
            {
            public enum UpdatableMenuItem
            {
            File,
            Exit,
            View,
            }
            }

            Now you can create a class to pass as an argument with the event that details the item and the change required.

            // UpdateMenuItemEventArgs.cs
            using System;

            namespace YourMdiApp
            {
            public delegate void UpdateMenuItemEventHandler(object sender, UpdateMenuItemEventArgs e);

            public class UpdateMenuItemEventArgs : EventArgs
            {
                private bool itemChecked;
                private bool enabled;
                private UpdatableMenuItem item;
                private bool visible;
            
                public UpdateMenuItemEventArgs(UpdatableMenuItem item, bool itemChecked, bool enabled, bool visible)
                {
                    this.item = item;
                    this.itemChecked = itemChecked;
                    this.enabled = enabled;
                    this.visible = visible;
                }
            
                public bool Checked
                {
                    get { return itemChecked; }
                }
                public bool Enabled
                {
                    get { return enabled; }
                }
                public UpdatableMenuItem Item
                {
                    get { return item; }
                }
                public bool Visible
                {
                    get { return visible; }
                }
            }
            

            }

            Now you need a base class that all your child forms can derive from that has the event and methods to raise it

            // FormChildBase.cs
            using System.Windows.Forms;

            namespace YourMdiApp
            {
            public class FormChildBase : Form
            {
            public event UpdateMenuItemEventHandler UpdateMenuItem;

                protected virtual void OnUpdateMenuItem(UpdateMenuItemEventArgs e)
                {
                    UpdateMenuItemEventHandler eh = UpdateMenuItem;
                    if (eh != null)
                        eh(this, e);
                }
                public void PerformUpdateMenuItem(UpdatableMenuItem item, bool itemChecked, bool enabled, bool visible)
                {
                    OnUpdateMenuItem(new UpdateMenuItemEventArgs(item, itemChecked, enabled, visible));
                }
            }
            

            }

            With this done, change your child forms to derive fr

            A 1 Reply Last reply
            0
            • L Lost User

              You can made one function on mainform which will return the value of ToolStripMenuItem. And before showing the form f1 assign the value of it to some variable to f1 as follows.

              f1.Somevariable=this.Returnvalueoftoolstripmenuitem();
              f1.Show();

              That's it. HTH

              Jinal Desai - LIVE Experience is mother of sage....

              D Offline
              D Offline
              Dave Kreskowiak
              wrote on last edited by
              #6

              This method also ties the second form to the first one forever. You could never use the second form indepentaly of the first. This is bad design...

              A guide to posting questions on CodeProject[^]
              Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                   2006, 2007, 2008
              But no longer in 2009...

              1 Reply Last reply
              0
              • D DaveyM69

                I would do it in a slightly long winded way, but it's far more flexible/extendable in future. All child forms that need this functionality should raise an event to signal to the parent that it wants to update it's menu. The children should never have access to the menu directly! The best way to do this is to have a enumeration of menu items that you can add to as required.

                // UpdatableMenuItem.cs

                namespace YourMdiApp
                {
                public enum UpdatableMenuItem
                {
                File,
                Exit,
                View,
                }
                }

                Now you can create a class to pass as an argument with the event that details the item and the change required.

                // UpdateMenuItemEventArgs.cs
                using System;

                namespace YourMdiApp
                {
                public delegate void UpdateMenuItemEventHandler(object sender, UpdateMenuItemEventArgs e);

                public class UpdateMenuItemEventArgs : EventArgs
                {
                    private bool itemChecked;
                    private bool enabled;
                    private UpdatableMenuItem item;
                    private bool visible;
                
                    public UpdateMenuItemEventArgs(UpdatableMenuItem item, bool itemChecked, bool enabled, bool visible)
                    {
                        this.item = item;
                        this.itemChecked = itemChecked;
                        this.enabled = enabled;
                        this.visible = visible;
                    }
                
                    public bool Checked
                    {
                        get { return itemChecked; }
                    }
                    public bool Enabled
                    {
                        get { return enabled; }
                    }
                    public UpdatableMenuItem Item
                    {
                        get { return item; }
                    }
                    public bool Visible
                    {
                        get { return visible; }
                    }
                }
                

                }

                Now you need a base class that all your child forms can derive from that has the event and methods to raise it

                // FormChildBase.cs
                using System.Windows.Forms;

                namespace YourMdiApp
                {
                public class FormChildBase : Form
                {
                public event UpdateMenuItemEventHandler UpdateMenuItem;

                    protected virtual void OnUpdateMenuItem(UpdateMenuItemEventArgs e)
                    {
                        UpdateMenuItemEventHandler eh = UpdateMenuItem;
                        if (eh != null)
                            eh(this, e);
                    }
                    public void PerformUpdateMenuItem(UpdatableMenuItem item, bool itemChecked, bool enabled, bool visible)
                    {
                        OnUpdateMenuItem(new UpdateMenuItemEventArgs(item, itemChecked, enabled, visible));
                    }
                }
                

                }

                With this done, change your child forms to derive fr

                A Offline
                A Offline
                AussieLew
                wrote on last edited by
                #7

                Thanks, there is a lot to absorb here ( for me anyway ) so I will work my way through it. I'm sure I will be wiser when I understand it completely. I have been struggling with fully understanding the concept of delegates, so this will prompt me to get a handle on that first.

                D 1 Reply Last reply
                0
                • A AussieLew

                  Thanks, there is a lot to absorb here ( for me anyway ) so I will work my way through it. I'm sure I will be wiser when I understand it completely. I have been struggling with fully understanding the concept of delegates, so this will prompt me to get a handle on that first.

                  D Offline
                  D Offline
                  DaveyM69
                  wrote on last edited by
                  #8

                  AussieLew wrote:

                  Thanks

                  You're welcome :-D

                  AussieLew wrote:

                  I have been struggling with fully understanding the concept of delegates, so this will prompt me to get a handle on that first.

                  Work through this article[^], it goes step by step. I wrote it for people exactly in your position.

                  Dave

                  If this helped, please vote & accept answer!

                  Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
                  BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                  A 1 Reply Last reply
                  0
                  • D DaveyM69

                    AussieLew wrote:

                    Thanks

                    You're welcome :-D

                    AussieLew wrote:

                    I have been struggling with fully understanding the concept of delegates, so this will prompt me to get a handle on that first.

                    Work through this article[^], it goes step by step. I wrote it for people exactly in your position.

                    Dave

                    If this helped, please vote & accept answer!

                    Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
                    BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                    A Offline
                    A Offline
                    AussieLew
                    wrote on last edited by
                    #9

                    Thanks Dave, I can see how using an event is the better way for the child form to cause a change in the parent form. Your article on events etc has helped clarify delegates etc to a great extent. Anything I'm missing I'm sure will "click" soon! The second part of my question regarded getting the state of the ToolStripMenuItem on the MainForm from the child form. So for example, if the MainForm ToolStripMenuItemConfirmDeletes item is Checked or not I can take the appropriate action when deleting a record on the child form. The only way I can see is to have a static variable (say in the startup code Static Class) bool confirmDeletes that is set whenever the MainForm ToolStripMenuItemConfirmDeletes.Checked property changes. This is accessible from all child forms and the MainForm as eg. Program.confirmDeletes Can ( and should ) this be done via an event or is using a Static variable acceptable practice? Lew

                    D 1 Reply Last reply
                    0
                    • A AussieLew

                      Thanks Dave, I can see how using an event is the better way for the child form to cause a change in the parent form. Your article on events etc has helped clarify delegates etc to a great extent. Anything I'm missing I'm sure will "click" soon! The second part of my question regarded getting the state of the ToolStripMenuItem on the MainForm from the child form. So for example, if the MainForm ToolStripMenuItemConfirmDeletes item is Checked or not I can take the appropriate action when deleting a record on the child form. The only way I can see is to have a static variable (say in the startup code Static Class) bool confirmDeletes that is set whenever the MainForm ToolStripMenuItemConfirmDeletes.Checked property changes. This is accessible from all child forms and the MainForm as eg. Program.confirmDeletes Can ( and should ) this be done via an event or is using a Static variable acceptable practice? Lew

                      D Offline
                      D Offline
                      DaveyM69
                      wrote on last edited by
                      #10

                      Glad it's helped :-D Good questions. Static variables/properties are almost never the correct way to go, that normally indicates a bad design. There are 3 methods that can be used. In order of easiest to most complex but also worst to best (as is often the case in programming!)

                      1. Easiest but normally worst
                        Static properties/variables as you mentioned. If using this, as they will need to be either internal or public I would strongly suggest properties with a private backing field.
                      2. Next best
                        A singleton class instance. See here[^] for a good tutorial by one of the C# gods.
                      3. Normally the best, but can be complex to implement depending on class hierachys
                        Let the parent form decide if the delete should be allowed and perform it. The children simply request the action and pass any required data via an event.

                      Not everyone would agree, and the 2nd method is very commonly used in production code as it gives better separation than the 3rd which is good OOP practice and therefore often the better solution.

                      Dave

                      If this helped, please vote & accept answer!

                      Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
                      BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                      A 1 Reply Last reply
                      0
                      • D DaveyM69

                        Glad it's helped :-D Good questions. Static variables/properties are almost never the correct way to go, that normally indicates a bad design. There are 3 methods that can be used. In order of easiest to most complex but also worst to best (as is often the case in programming!)

                        1. Easiest but normally worst
                          Static properties/variables as you mentioned. If using this, as they will need to be either internal or public I would strongly suggest properties with a private backing field.
                        2. Next best
                          A singleton class instance. See here[^] for a good tutorial by one of the C# gods.
                        3. Normally the best, but can be complex to implement depending on class hierachys
                          Let the parent form decide if the delete should be allowed and perform it. The children simply request the action and pass any required data via an event.

                        Not everyone would agree, and the 2nd method is very commonly used in production code as it gives better separation than the 3rd which is good OOP practice and therefore often the better solution.

                        Dave

                        If this helped, please vote & accept answer!

                        Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
                        BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)

                        A Offline
                        A Offline
                        AussieLew
                        wrote on last edited by
                        #11

                        Thanks once again! I will try your option 3 I think. I have spent a lot of time getting one Form right with data validation and save, edit delete actions etc. I have a few forms along similar lines to come yet. My next task was to simplify creation of these additional forms. By having the child form pass the parent form data through events and having the parent form look after some of the actions, like add, edit, delete, save etc this would be some things that would not have to be duplicated in each form. This is starting to get off topic now but I guess for similar forms with different data sources etc I should set up a form with a constructor that takes the parameters I want to change, plus events etc for form interaction, and use that as a basis for all my similar forms. Lew

                        D 1 Reply Last reply
                        0
                        • A AussieLew

                          Thanks once again! I will try your option 3 I think. I have spent a lot of time getting one Form right with data validation and save, edit delete actions etc. I have a few forms along similar lines to come yet. My next task was to simplify creation of these additional forms. By having the child form pass the parent form data through events and having the parent form look after some of the actions, like add, edit, delete, save etc this would be some things that would not have to be duplicated in each form. This is starting to get off topic now but I guess for similar forms with different data sources etc I should set up a form with a constructor that takes the parameters I want to change, plus events etc for form interaction, and use that as a basis for all my similar forms. Lew

                          D Offline
                          D Offline
                          DaveyM69
                          wrote on last edited by
                          #12

                          Yep - you're getting there and thinking along the right lines now! The next problem you may come across is getting the result of the action request back to the child. There are two good methods for this. 1. You can have a property in your event args that the main (parent) from sets. This is the normally recommended method. 2. Sometimes a more intuitive way is to forget about the standard event signature and create your own delegate that actually returns a result. I've knocked up this quick sample to demonstrate.

                          using System.Windows.Forms;

                          namespace CpDelegateSample
                          {
                          public partial class FormMain : Form
                          {
                          private bool toggle;

                              public FormMain()
                              {
                                  InitializeComponent();
                                  toggle = false;
                                  FormSub formSub = new FormSub();
                                  formSub.DeleteRequest += new FormSub.DeleteRequestEventHandler(formSub\_DeleteRequest);
                                  formSub.Show();
                              }
                          
                              private bool formSub\_DeleteRequest(string data)
                              {
                                  // If OK, do delete and return true; otherwise, return false
                                  bool result = toggle;
                                  string message = result ? "Allowing" : "Denying";
                                  MessageBox.Show(string.Format("{0} {1}", message, data));
                                  toggle = !toggle;
                                  return result;
                              }
                          }
                          

                          }

                          using System;
                          using System.Windows.Forms;

                          namespace CpDelegateSample
                          {
                          public partial class FormSub : Form
                          {
                          public delegate bool DeleteRequestEventHandler(string data);

                              public event DeleteRequestEventHandler DeleteRequest;
                          
                              public FormSub()
                              {
                                  InitializeComponent();
                                  Click += new EventHandler(FormSub\_Click);
                              }
                          
                              void FormSub\_Click(object sender, EventArgs e)
                              {
                          
                                  OnDeleteRequest("ABC");
                                  OnDeleteRequest("DEF");
                              }
                          
                              protected virtual void OnDeleteRequest(string data)
                              {
                                  DeleteRequestEventHandler eh = DeleteRequest;
                                  if (eh != null)
                                  {
                                      bool result = eh(data);
                                      string message = result ? "Allowed" : "Denied";
                                      MessageBox.Show(string.Format("{0} {1}", message, data));
                                  }
                              }
                          }
                          

                          }

                          Dave

                          If this helped, please vote & accept answer!

                          Binging is like googling, it just feels dirtier. Please take your VB.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups