TekGiant
TekGiant

Reputation: 1202

Stored variable that shouldn't be getting changed is getting changed

I'm working on making some custom transition effects with some panels, and to ensure I can return panels back to the state in which I needed them, when the Form load method is called, I search the form controls for all the panels, and add the respective panels to a list of panels so that I can refer back to their default values later on.

internal List<Panel> PDefaults = new List<Panel>();

foreach (var panel in this.Controls)
{
    if (panel.GetType() == typeof (Panel) && Name != "panel1")
    {
        PDefaults.Add((Panel) panel);
    }
}

don't worry about that panel1, that's just one of the panels I don't care to mess with, so I don't need it in the list.

Now, I have a button that's supposed to trigger a method in a custom class I've made

private void button1_Click(object sender, EventArgs e)
{
    Mover.EDown(ref panel2, PDefaults[3].Height, PDefaults[3].Height + 50);
}

Here's the class's method

public static void EDown(ref Panel panel, int collapsedY, int expandedY)
{
    if (panel.Height == collapsedY)
    {
        for (var i = panel.Height; i <= expandedY; i+=2)
        {
            panel.Height = i;
            panel.Refresh();
            Thread.Sleep(10);
        }
    }
    else 
    {
        for (var i = panel.Height; i >= collapsedY; i-=2)
        {
            panel.Height = i;
            panel.Refresh();
            Thread.Sleep(10);
        }
    }
}

I use the same button, in sort of a toggle like manner, so I'm not sure if that's the issue here, but on the first click, this works, because it meets the if condition on the Mover class's EDown method shown above; however, on the next click, it still meets the first condition. What I found through some debugging and looking at variables before and after, it appears that the PDefaults[3].Height value is actually getting altered, when all I'm doing is pointing at it, or at least that's what I think I'm doing. I stored the panel's values in the list specifically so I don't have a changing value, but it almost seems as if each time I refer to the list, the list is referring back to the panel that was stored in it, and getting new values. If anyone has a recommendation on how to get around this or even do it better, then I'd appreciate it.

Upvotes: 0

Views: 57

Answers (1)

Yacoub Massad
Yacoub Massad

Reputation: 27871

The Panel is a reference type. When you save your panels into a list, you are not saving copies of the panels, you are saving a references to the same panels.

I suggest that instead of storing the panels in a list, store the panel heights in the list. The height property is of type int. This means that a copy of it will be stored in the list.

UPDATE:

Here is a sample class that you can use to store more information about the Panel:

public class PanelInformation
{
    public int Height { get; set; }
    public int Width { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
}

Upvotes: 1

Related Questions