0
\$\begingroup\$

I'm making an app that's similar to an alarm, the user enters time and days, for days I'm using toggles,and storing the values of toggles states in a list which is stored in a list that contain all the inputs of the type days, then the user could edit any of his inputs, his old input are supposed to be shown there , but the problem is even when I'm storing them, old values are changing when I add new elements,(that's when currentToggle is changing) so when he press edit values aren't the same as he entered them

I think it has something to do with nested lists but I can't figure out how, ( assigning hours and minutes is perfectly working and both are normal lists)

the confirm method is for when the user confirm his choice, and there's edit button that open a panel ,its values are the same as the user entered them before

the index gives the number of the selected group of input, dayholder is the gameobject that contains all the toggles , and that's the part of the code that's related to what I've said

Toggle[] toggles;
List<bool> currentToggle = new List<bool>();
List <List<bool>> daysAll = new List<List<bool>>();


void Start () {
    toggles = dayHolder.GetComponentsInChildren<Toggle>();
}
public void confirm()
{

    checkON();
    daysAll.Add(currentToggle);
}
 public void editBut()
{
    GameObject panelC = EventSystem.current.currentSelectedGameObject.gameObject.transform.parent.gameObject;
    int index = panelC.transform.parent.gameObject.transform.GetSiblingIndex();
    assignDays(index);
}
void assignDays(int index)
{
    for (int i = 0; i < daysAll[index].Count; i++)
    {
        if (daysAll[index][i] == true)
            toggles[i].isOn = true;
    }
}
public void checkON()
{
    currentToggle.RemoveAll(item => item != null);
    for (int i = 0; i < toggles.Length; i++)
    {
        if (toggles[i].isOn)
            currentToggle.Add(true);
        else
            currentToggle.Add(false);
    }    

}
\$\endgroup\$
5
  • \$\begingroup\$ Can you walk us through a test case that demonstrates the problem? eg. "1. The user starts the app. 2. The app initializes the list state to... 3. The player presses button A 4. The list state updates to.... 5. The user presses button B. 6. The list state should be... but instead I observe the state to be..." \$\endgroup\$
    – DMGregory
    Commented Nov 13, 2018 at 22:24
  • \$\begingroup\$ first the user enter a time and date, then confirm it, so these data are stored in list to show them to the user when he want to edit them,but when I press edit it shows me the last input I entered, the change happens when I add new time ,more specifically ,when currentToggle changes , mostly because of what @DMGregory said that Lists in C# are reference types \$\endgroup\$
    – Abeer
    Commented Nov 16, 2018 at 16:52
  • \$\begingroup\$ I think this explanation will be clearer if you edit it into your question itself. Then you can format it step by step, showing the complete state after each step, rather than squeezing it all into a comment. \$\endgroup\$
    – DMGregory
    Commented Nov 16, 2018 at 17:04
  • \$\begingroup\$ oh sorry didn't notice the comment is yours too, I tried to edit it but can't understand how to format it step by step ! \$\endgroup\$
    – Abeer
    Commented Nov 16, 2018 at 20:02
  • \$\begingroup\$ actually every thing is working fine now, what you said earlier solved the actual problem , later I found out that I've been missing the else statement here for (int i = 0; i < daysAll[index].Count; i++) { if (daysAll[index][i] == true) toggles[i].isOn = true; else toggles[i].isOn = false; } Thanks for your help \$\endgroup\$
    – Abeer
    Commented Nov 16, 2018 at 20:46

1 Answer 1

0
\$\begingroup\$

It's a bit hard to say without a more complete example, but from what we can see so far, it looks like you're populating your currentToggle list using the current states of the Toggle components configured by the user, then putting that list into your toggles list.

Are you assuming that this creates a copy of the currentToggle list, saving its values so that the next time you call checkON() and clear the list, the previous copies saved in toggles should retain their values?

If so, that could be the cause of the error you describe. Lists in C# are reference types, meaning that when you write

myListOfLists.Add(myList);

you're storing a reference to myList into myListOfLists - and that reference still points to the same data structure / the same memory as the myList variable. No data has been copied, so if you later change the contents myList, you're also changing the contents of the version referenced via myListOfLists.

If you want to clone a list, so that the clone retains its values no matter what you do to the original list, you can instead write:

myListOfLists.Add(new List(myList));

which will retain the list's Add/Remove functionality, or

myListOfArrays.Add(myList.ToArray());

if you don't need to resize the collection again, and can deal with the copy as a fixed-size collection going forward.

You could also use the CopyTo() methods to write your list's contents into an existing array, to save allocating fresh memory for the copy.

\$\endgroup\$
1
  • \$\begingroup\$ So I understand that in my case I should write daysAll.Add(new List<bool> (currentToggle)); , but now if I have first list with number 6 and 7 true , and second one with 1 and 2 true , all my lists will have numbers 1,2,6,7 as true \$\endgroup\$
    – Abeer
    Commented Nov 16, 2018 at 16:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .