0

I previously created a program that displays data from a text file into a listview and users are able to click a name in the listview and it displays the phone number for that name. Now I'm trying to add a new form to the program that allows the user to select a name from a combobox which then displays the name in a textbox and allows a user to change the name and save it in the text file.

Original Program

Anyways, I'm trying to make the load event from the original program accessible in the new form and I can't seem to figure out how to do that. Here is my code:

public partial class VendorsDictionary : Form
{
    public VendorsDictionary()
    {
        InitializeComponent();
    }

    private Dictionary<string,string> vendorPhones = new Dictionary<string,string>();

    public void VendorsDictionary_Load(object sender, EventArgs e)
    {
        string currentLine;
        string[] fields = new string[2];
        StreamReader vendorReader = new StreamReader("Vendor.txt");

        while (vendorReader.EndOfStream == false)
        {
            currentLine = vendorReader.ReadLine();
            fields = currentLine.Split(',');

            vendorPhones.Add(fields[1], fields[6]);

            string[] name = { fields[1] };
            string[] city = { fields[3] };
            string[] state = { fields[4] };
            string[] zipcode = { fields[5] };
            string[] phone = { fields[6] };

            for (int i = 0; i < name.Length; i++)
            {
                lvDisplay.Items.Add(new ListViewItem(new[] { name[i], city[i], state[i], zipcode[i] }));
            }    
        }

        vendorReader.Close();
    }

    private void lvDisplay_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (lvDisplay.SelectedItems.Count>0)
        {
            ListViewItem item = lvDisplay.SelectedItems[0];
            lblName.Text = item.SubItems[0].Text;
            lblPhone.Text = vendorPhones[item.SubItems[0].Text];
        } 
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
        UpdateVendor updateVendor = new UpdateVendor();
        updateVendor.Show();
    }
}

I've tried changing it to static and a number of other ideas I've found here but can't seem to get it to work. Any help would be appreciated!

Rufus L
  • 36,127
  • 5
  • 30
  • 43
Dubisttot
  • 19
  • 2
  • 6
  • So why do you need the `VendorsDictionary_Load` function? Taking that this function only saves results to `lvDisplay` – Ben May 14 '17 at 17:15
  • Possible duplicate of [How to share data between forms?](http://stackoverflow.com/questions/3800603/how-to-share-data-between-forms) – Rufus L May 14 '17 at 17:27
  • Create a public property on your `UpdateVendor` form (let's call it `public string Name;`, and set it to the combobox selected item (name). Then use `updateVendor.ShowDialog();` to launch the form (`ShowDialog()` will block execution on your `VendorsDictionary` form until the `updateVendor` form is closed. Then you can check the `updateVendor.Name` property and you have the name the user selected. – Rufus L May 14 '17 at 17:32
  • @RufusL how would I go about setting it to the combobox selected item? Wouldn't I need populate the combobox with the names? Sorry if this is a dumb question, I just started learning how to code =/ – Dubisttot May 14 '17 at 18:11
  • Oh, I see I misunderstood the full problem. I will try to post an answer later, but basically it is always a similar answer. You can either make the method public on your first form (probably not the whole form load method, but some other method that returns the names), and then pass an instance of form1 to form2. Or, get the list of names in form1 and then pass that list to form2, either as a parameter to a form2 method, or as a form2 property. – Rufus L May 14 '17 at 20:58

1 Answers1

1

You don't need all that code in your VendorsDictionary_Load method. You can really clean it up. I will show you how.

Add this class to your project:

public class Vendor
{
    public string City { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

Add this method to VendorsDictionary:

public static IEnumerable<Vendor> LoadVendors()
{
    var vendors =
        File.ReadAllLines("Vendor.txt").Select(x => x.Split(','))
            .Select(x =>
            new Vendor
            {
                Name = x[1],
                City = x[3],
                State = x[4],
                ZipCode = x[5],
                Phone = x[6]
            }).ToList();

    return vendors;
}

Change the code in VendorsDictionary_Load to this:

public void VendorsDictionary_Load(object sender, EventArgs e)
{
    var vendors = LoadVendors();
    foreach (var thisVendor in vendors)
    {
        vendorPhones.Add(thisVendor.Name, thisVendor.Phone);
        lvDisplay.Items
            .Add(new ListViewItem(new[] { thisVendor.Name, thisVendor.City,
                thisVendor.State, thisVendor.ZipCode }));
    }
}

Use the LoadVendors method wherever you want:

var someOtherUsage = VendorsDictionary.LoadVendors();

To improve this code, send a path to LoadVendors so you can load the vendors from any location. Also, VendorDictionary is not a good name for a form.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64