0

Say I have a list called listOfFruits in my main form. In a second form I've made I want the user to be able to remove items from that list to a second list called removedFruits. Currently I know I can access these lists in my second form simply passing them as parameters in the form constructor. However c# can't do pointers (correct?) so how can I effect the main form's copy of these lists from my second form? Because currently any changes to those lists in my second form don't effect the main form's original copy of the lists. If I were to remove 5 fruits from the listOfFruits passed to my second form then after finishing my work the main form would still still have a full listOfFruits and an empty removedFruits. Is there a simple fix to this? Maybe a get/set or a way to add/remove items from the original lists from the second form? Maybe the answer is in some sort of accessor stuff?

EDIT: To clarify; I want to add to one list, and remove from another. Not add/remove to the same list. Not sure if this matters entirely but I figured I'd be specific here in case it does.

EDIT2: I think the issue is I'm copying the original list from the first form and not editing it directly. Can someone fix my code so I can access the original list from my second form instead of making a copy of the list?

public partial class ListSelector : Form
    {
        private string windowName = Form1.typeOfModuleAdded;
        public List<IOModule> innerIOList;
        IOModule cardAdded = null;

        public ListSelector(List<IOModule> cardList)
        {
            this.Text = windowName;
            innerIOList = cardList;
            InitializeComponent();
            InitializeList();
        }
    private void InitializeList()
    {
        if (windowName == "Drive")
        {
            string[] listDrives = { "ACS880", "test" };
            listBox1.Items.AddRange(listDrives);
        }

        else if (windowName == "IOBlock")
        {
            if (!innerIOList.Any())
            {
                MessageBox.Show("No cards loaded! Please import cards from IO List.", "Error Empty Data", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
            foreach (IOModule card in innerIOList)
            {
                cardAdded = card;
                listBox1.Items.Add(card.name);
            }
        }
        else if (windowName == "Local Card")
        {
            string[] listLocals = { "1756-EN2T", "test" };
            listBox1.Items.AddRange(listLocals);
        }
        else if (windowName == "Processor")
        {
            string[] listProcessors = { "1756-L71S", "test" };
            listBox1.Items.AddRange(listProcessors);
        }
    }

    private void addBtn_Click(object sender, EventArgs e)
    {
        if (listBox1.SelectedItem != null)
        {
            Form1.SetModule(listBox1.SelectedItem.ToString());
            Form1.confirmedAdd = true; 
            this.Close();
        }
        else if (cardAdded != null)
        {
            innerIOList.Remove(cardAdded);
        }
        else
        {
            MessageBox.Show("No module selected!");
        }
    }

and here's how I pass the list to that form from my first form:

        ListSelector test = new ListSelector(ioList);
        test.ShowDialog();

where ListSelector is the name of my second form, and ioList is the list im passing to it.

EDIT3: added more code

Capn Jack
  • 1,201
  • 11
  • 28
  • 1
    Could you show your code that you're having trouble with, then we might be able to help you a little more? :) – Geoff James Oct 12 '16 at 13:23
  • How about creating a new .cs file (and a new class) and putting those lists in this class as statics and reference them from both forms. e.g. MyStatics.ListOfFruits and MyStatics.RemovedFruits. – Jure Oct 12 '16 at 13:23
  • `List` is reference type and when you pass it to another form, all changes which you make on the list will be visible in your first form too. Probably you have created another list from your original list (using `ToList` or something else) and that's why you can't see the changes in your original list. – Reza Aghaei Oct 12 '16 at 13:33
  • @RezaAghaei yup this is exactly it. Here I'll add an edit to my OP to show you what I have. I have no clue how to edit the original list instead of making a copy of it to access the content. – Capn Jack Oct 12 '16 at 13:40
  • @GeoffJames adding some now, read my cloning problem I wrote RezaAghaei about. Could you fix my snytax so I'm editing the original list from the first form instead of making a copy in my second form? – Capn Jack Oct 12 '16 at 13:41
  • What's `InitializeList();`? And show how do you pass `cardList` to the form. – Reza Aghaei Oct 12 '16 at 13:44
  • @RezaAghaei added what you were looking for, Initialize list just populates my listbox in the second form with data. Part of it uses the data from the list I pass it. And I passed card list by making a new form called test as type ListSelector (which is the name of my second form) – Capn Jack Oct 12 '16 at 13:48
  • I think you should look at the place you call the `ListSelector`constructor. Do you reallyreallyreally use the same List you're looking at in `Form1`. (again: no `new List(cardList)` or `cardList.ToList()`). If yes, i point you to the 2nd recommendation in my answer below. – TheHowlingHoaschd Oct 12 '16 at 13:50
  • The changes that you make on `ListBox` doesn't have any impact on the list which you passed to the form. – Reza Aghaei Oct 12 '16 at 13:51
  • @RezaAghaei Just added the function that I want to edit the list with. It's called addBtn_Click. See where I have innerIOList.Remove(cardAdded). – Capn Jack Oct 12 '16 at 13:55
  • @TheHowlingHoaschd I'm gunna use your second answer if I can't get a way to directly access the list. It seems like more of a bandaid fix but hey it'll work if I really can't get a more official answer here. – Capn Jack Oct 12 '16 at 13:59
  • 1
    It seems you are directly accessing the List. Your problem may be, that your changes to the List aren't reflected in your UI (i.e. your ListBoxes). You will have to do that manually whever you edit the List i think. – TheHowlingHoaschd Oct 12 '16 at 14:09
  • @TheHowlingHoaschd Jeez that's a crazy coincidence. So I fixed my problem, The error was I was never actually removing a card because of my else if statement in my addbutton method. It had the same argument as the preceeding if statement.. Anyway I fixed that and now the List is properly being edited in the main form, however just like you said my listbox isn't removing the cards from the displayed list in the UI even though the card doesn't exist in the list it was passed. How do I "do that manually" as you recommend? I'm dumb founded at how it's populating the list with non-existent items. – Capn Jack Oct 12 '16 at 14:15
  • @TheHowlingHoaschd okay and further debuggin has revealed that it is removing cards from the list, just not the right one. It's currently removing the last card added. Now I have to figure out how to identify the last card removed... Can't do it by name because the object I remove has to be of type IOModule. And the NodeSelected will only contain the name of the IOModule. – Capn Jack Oct 12 '16 at 14:18
  • @CapnJack I shared an answer. Hope it helps you to have better understanding of the probable issues. – Reza Aghaei Oct 12 '16 at 14:28
  • 1
    Also you may find this post useful: [Connect List to a ListBox](http://stackoverflow.com/questions/33623991/connect-listt-to-a-listbox) – Reza Aghaei Oct 12 '16 at 14:31
  • @RezaAghaei they are useful thanks! I've done too much now though to go and change things around but I'm definitely remembering listbox.datasource. That'll come in handy later :) – Capn Jack Oct 12 '16 at 20:47

3 Answers3

1

I assume that you have created a second list in your second form that is filled with the items of the first form's list. Then changes on the second list aren't reflected in the first list. You have to use the same reference of the list.

public Form2(List<Fruit> listOfFruits)
{
    this._listOfFruits = listOfFruits;
}

private List<Fruit> _listOfFruits;
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Does the code you've provided there make a copy of the original list? That's what it seems like to me. If it doesn't would you mind explaining why not? I don't really see the difference in what I wrote and what you've got here. Because what I've wrote is only making a copy, not directly affecting the original list. :( – Capn Jack Oct 12 '16 at 13:51
  • @CapnJack: no copy, i just assign the same reference to another variable. Since the list is a reference type all changes will also reflect the list in the first form. – Tim Schmelter Oct 12 '16 at 13:55
1

"However c# can't do pointers (correct?) so how can I effect the main form's copy of these lists from my second form?"

No, not correct. Any object reference (for instance, of a List<Fruit>) is still very much a pointer to a place in memory, and if you pass the same List<Fruit> object to both Forms, they share the same List.

I don't know why your changes to your listOfFruits don't chow up in your first Form. I would check the following things:

  1. Are you 100% sure you use the same List<Fruit> object in both Forms. (If you create a new List like this: new List<Fruit>(listOfFruits) it is NOT the same List)

  2. Does the first Form have any way of finding out, that the List has changed? Possible using a Timer with recurring checks, or (my favorite) triggering an event when you change something, and subscribe an EventHandler in the first Form to the event.

0

Instead using a public field, try to use property and on creating your new ListSelector pass the list to the property.

public partial class ListSelector : Form
{
    private string windowName = Form1.typeOfModuleAdded;
    private List<IOModule> innerIOList;
    IOModule cardAdded = null;

    public List<IOModule> CardList 
    {
         get 
         {
              return innerIOList; 
         }
         set
         {
              innerIOList = value;
              InitializeList();
         }
    }

    public ListSelector()
    {
        this.Text = windowName;
        InitializeComponent();
    }

When creating your new ListSelector object

ListSelector ls = new ListSelector();
ls.CardList = your mainform list of IOModule here
ls.ShowDialog();
zer09
  • 1,507
  • 2
  • 28
  • 48
  • wait if you aren't passing the original list from the first form to this form, how are you getting that list info? – Capn Jack Oct 12 '16 at 13:57
  • @CapnJack No, you can pass the list using the second line of the code see the **ls.CardList = your mainform list of IOModule here**, also edited the property to match on your code edit. – zer09 Oct 12 '16 at 14:08