Search code examples
c#comboboxnetwork-interface

How to add Network Interfaces to a Combobox and resolve ip based on selected interface?


For practice i want to create a selectable dropdown box with available Network Interfaces ( localhost ), and upon selecting one of them there should be an ip resolution ( writes ip4 to one textbox and ip6 to the next box ) for that selected interface

So far i have :

private void localhostip(object sender, EventArgs e)
    {
     var mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            var moc = mc.GetInstances();

            foreach (var mo in moc)
            {
                if ((bool)mo["ipEnabled"])
                {
                     comboBox1.Items.Add(mo["Caption"].ToString());
                }
            }
}

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //ACQUIRE THE IP4 & IP6 ADDRESSES
            string host = Dns.GetHostName();
            IPAddress[] ips = Dns.GetHostAddresses(host);

            tblocalhost.CharacterCasing = CharacterCasing.Upper;
            tblocalip.CharacterCasing = CharacterCasing.Upper;
            tblocalhost.Text = host;


            if (comboBox1.SelectedIndex == 0)
            {
                tblocalip.Text = null;
                tblocalip6.Text = null;

                foreach (IPAddress ip4 in ips.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork))
                {
                    tblocalip.Text = ip4.ToString();
                }

                foreach (IPAddress ip6 in ips.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6))
                {
                    tblocalip6.Text = ip6.ToString();
                }
            }

            if (comboBox1.SelectedIndex == 1)
            {
                tblocalip.Text = null;
                tblocalip6.Text = null;

                foreach (IPAddress ip4 in ips.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork))
                {
                    tblocalip.Text = ip4.ToString();
                }

                foreach (IPAddress ip6 in ips.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6))
                {
                    tblocalip6.Text = ip6.ToString();
                }
            }
        }

Notice : localhostip is executed on Form launch.

So now how do i bind the choosing of the Interface Index to the actual checking of that Interface's IP ?

And if possible suggest corrections/additions to my code, to keep it simple and understandable for me , i dont want to just copy someone else's code and be done, i wanna learn


Solution

  • When getting adapter names and IP addresses, I suggest something like the following:

    By storing them in a dictionary you can access them by their adapter name.

    Please see my comments for detailed explanation on the process I used.

    I hope this helps, I tried to be thorough with the comments.

    Notes for the method for storing the adapter names and IPs

    //create a dictionary storing the name and address of each adapter
    public Dictionary<string,IPAddress> ip4ByAdapter = new Dictionary<string,IPAddress>();
    public Dictionary<string,IPAddress> ip6ByAdapter = new Dictionary<string,IPAddress>();
    
    void GetIpsAndAdapters()
    {
        //Get the network interfaces
        NetworkInterface[] netInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    
        //don't forget to clear the combo box
        comboBox1.Items.Clear();
    
        foreach(NetworkInterface adapter in netInterfaces)
        {
            //get the IP Properties for short hand
            IPInterfaceProperties ipProps = adapter.GetIPProperties();
    
            //set a default value of 0.0.0.0
            IPAddress ipv4 = new IPAddress(0); 
    
            //if it has one, store the ipv4 of the current adapter
            if(ipProps.UnicastAddresses.Count > 1)
                ipv4 = ipProps.UnicastAddresses[1].Address;
    
            //set a default value of 0.0.0.0
            IPAddress ipv6 = new IPAddress(0);
    
            //if it has one, store the ipv6 of the current adapter
            if (ipProps.UnicastAddresses.Count > 0)
                ipv6 = ipProps.UnicastAddresses[0].Address;
    
            //store the matching pair of adapter and ip address in dictionary
            //check for duplicates (loopbacks perhaps) and ignore them
            if(!ip4ByAdapter.ContainsKey(adapter.Name))
                ip4ByAdapter.Add(adapter.Name, ipv4);
    
            //same for ipv6
            if(!ip6ByAdapter.ContainsKey(adapter.Name))
                ip6ByAdapter.Add(adapter.Name, ipv6);
    
            comboBox1.Items.Add(adapter.Name);
        }
    }
    

    Notes for the comboBox1.SelectedIndexChanged Event

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        //if we haven't selected an item yet, just do nothing
        if(comboBox1.SelectedIndex == -1 || comboBox1.SelectedItem is null)
            return;
    
        //reset the textboxes, just to an empty string
        tblocalip.Text = "";
        tblocalip6.Text = "";
    
        //if the Dictionary contains a matching adapter to the one selected in the combo box
        if(ip4ByAdapter.ContainsKey(comboBox1.SelectedItem.ToString()))
        {
            //then show it
            tblocalip.Text = ip4ByAdapter[comboBox1.SelectedItem.ToString()].ToString();
        }
    
        //same for ipv6
        if(ip6ByAdapter.ContainsKey(comboBox1.SelectedItem.ToString()))
        {
            tblocalip6.Text = ip6ByAdapter[comboBox1.SelectedItem.ToString()].ToString();
        }
    }