1

In my application I have two forms (see image below). Clicking on "Add" button shows the second "Add wireless network" form.

enter image description here

After filling the form and clicking on "OK", second form adds the new profile and updates the wifi network profiles in the first form. There is a RefreshProfiles function in the first form and I call it in the second form with this:

((MainForm)this.Owner).RefreshWiFiProfiles();

and the "Add" button's code is this:

private void AddButton_Click(object sender, EventArgs e)
{
    NewNetworkForm newNetworkForm = new NewNetworkForm();
    newNetworkForm.Owner = this;
    newNetworkForm.ShowDialog();
}

This setup is working fine, but since the number of lines increased as I added new things, I wanted to divide the code. So I created a class to contain some functions.

namespace WirelessNetworkManager
{
    public class Tools
    {
        public static void RefreshWiFiProfiles(ListView ListViewControl)
        {
            // clear old list
            ListViewControl.Items.Clear();

            // update it
        }
    }
}

I call the method in the first form with this:

Tools.RefreshWiFiProfiles(ProfilesListView);

and it's working fine. The problem is, since I need to update the profiles list from the second form too, I need to call this in NewNetworkForm. I can access and pass the ProfilesListView in MainForm because it's in there. How can I pass a control that is in MainForm to a method in NewNetworkForm and modify it? Or is there a better approach to do this?

File structure

  • MainForm.cs (WirelessNetworkManager.MainForm)
  • NewNetworkForm.cs (WirelessNetworkManager.NewNetworkForm)
  • Tools.cs (WirelessNetworkManager.Tools)
akinuri
  • 10,690
  • 10
  • 65
  • 102
  • The better approach would be to have a ManagerTools that deals with neutral data and not with controls. The short solution is to move this logic to after the ShowDialog() call. – H H Jul 05 '15 at 07:50

2 Answers2

2

You can set the Modifiers property of your ProfilesListView in Form2 to Public or Internal (It's Private by default) then you can access ProfilesListView of Form2 like this : Form2.ProfilesListView

For example:

ProfilesList.Refresh(Form2.ProfilesListView);

Your mistake is : You are creating a new Form when you are using RefreshWiFiProfiles() method.

You should access to existing Form2, for example if Form2 is Owner of Form1, this code works :

Form ownerForm = (Form)this.Owner;
Tools.RefreshWiFiProfiles(ownerForm.ProfilesListView);

Here is the complete example:

Form1 declaration:

  1. Add a ListView to Form1, Set it's Modifiers to Public and add some items in it.
  2. Add a Button to show Form2
  3. Add a Button to clear Form2 ListView

Form1 Code:

public partial class Form1 : Form
    {
        Form2 form2;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnShowForm2_Click(object sender, EventArgs e)
        {
            form2 = new Form2();
            form2.Owner = this;
            form2.Show();
        }

        private void btnClearForm2List_Click(object sender, EventArgs e)
        {
            Tools.RefreshWiFiProfiles(form2.lstViewOfForm2);
        }
    }

Form2 declaration:

  1. Add a ListView to Form2, Set it's Modifiers to Public and add some items in it.
  2. Add a Button to clear Form1 ListView

Form2 Code:

public partial class Form2 : Form

    {
        public Form2()
        {
            InitializeComponent();
        }

        private void btnClearForm1List_Click(object sender, EventArgs e)
        {
            Form1 form1 = (Form1)this.Owner;
            Tools.RefreshWiFiProfiles(form1.lstViewOfForm1);
        }
    }

Declaration of Tools Class:

public static class Tools
{
    public static void RefreshWiFiProfiles(ListView listView)
    {
        listView.Clear();
    }
}
Afshin Aghazadeh
  • 547
  • 4
  • 17
  • I don't think I follow you. `ProfilesListView` is in the first form and I'll update it from the second form. And how do I make the second form owner of the first form? Can you give me a full example instead of one or two line of code? Something like this [fiddle](http://jsfiddle.net/L22L4bqf/2/). Just fill the blocks. Since I'm a beginner, I'm having hard time figuring it out. I've also updated the question. It should be more clear now. – akinuri Jul 05 '15 at 10:40
  • I don't know if your code is working, because clearly you misunderstood my problem. There is no ListView in the second form... I found a solution now. Thanks anyway. – akinuri Jul 06 '15 at 05:58
  • I know, I just made a complete sample to make you clear that you can access from **parent form** to **child form** and **the other way**. If you run my example you will understand, – Afshin Aghazadeh Jul 06 '15 at 19:29
0

I tried implementing this. __curious_geek's answer and it worked fine.

MainForm.cs

namespace WirelessNetworkManager
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void AddButton_Click(object sender, EventArgs e)
        {
            // passing "this" (MainForm) to the second form
            NewNetworkForm newNetworkForm = new NewNetworkForm(this);
            newNetworkForm.ShowDialog();
        }
    }
}

NewNetworkForm.cs

namespace WirelessNetworkManager
{
    public partial class NewNetworkForm : Form
    {
        public NewNetworkForm()
        {
            InitializeComponent();
        }

        // a local variable to reference the first form (MainForm)
        private MainForm mainForm = null;

        // a second overloaded constructor accepting a form
        public NewNetworkForm(Form callingForm)
        {
            // mainForm now refers to the first form (MainForm)
            mainForm = callingForm as MainForm;
            InitializeComponent();
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            // create wifi profile with user input

            // accessing the ListView using this.mainForm
            Tools.RefreshWiFiProfiles(this.mainForm.ProfilesListView);

            this.Close();
        }
    }
}

Tools.cs

namespace WirelessNetworkManager
{
    public class Tools
    {
        public static void RefreshWiFiProfiles(ListView ListViewControl)
        {
            ListViewControl.Items.Clear();

            // iterate through wifi profiles and populate ListViewControl
        }
    }
}

Also the control element's (ListViewControl) Modifiers should be set to Public or Internal. Otherwise you'll get an error.

'WirelessNetworkManager.MainForm.ProfilesListView' is inaccessible due to its protection level
Community
  • 1
  • 1
akinuri
  • 10,690
  • 10
  • 65
  • 102