1

I'm trying to create an undo function for changes made in a PropertyGrid. To accomplish this I push an object to a Stack before assigning the object to the PropertyGrid. To my surprise the object in the stack changes accordingly to the changes made in the PropertyGrid.

Why is this happening?

public class Employee
{
    [Browsable(false)]
    public int employeeKey { get; set; }

    [DisplayName("Name")]
    [Description("The name of the employee.")]
    public string employeeName { get; set; }

    [DisplayName("Active")]
    [Description("Indicates whether the employee is currently employed.")]
    public bool employeeIsActive { get; set; }
}

public partial class frmProperties : Form
{
    public object propertyGridObject;
    private Stack<object> _stack;

    public frmProperties()
    {
        InitializeComponent();
    }

    private void frmProperties_Load(object sender, EventArgs e)
    {
        _stack = new Stack<object>();
        _stack.Push(propertyGridObject);

        propertyGrid.SelectedObject = propertyGridObject;
    }

    private void btnReset_Click(object sender, EventArgs e)
    {
        if (_stack.Count > 0)
        {
            propertyGrid.SelectedObject = _stack.Pop();
        }
    }
}

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

    private void btnViewProperties_Click(object sender, EventArgs e)
    {
        Employee employee = new Employee()
        {
            employeeKey = 123,
            employeeName = "John Smith",
            employeeIsActive = true
        };

        using (frmProperties frm = new frmProperties())
        {
            frm.propertyGridObject = employee;
            frm.ShowDialog(this);
        }
    }
}
tfeitsma
  • 23
  • 2
  • 3
    Because your employee object is a reference type. You need to clone the object (make a copy) since mutating any properties will affect both places you are referencing the object, there is only one copy of it in memory – Charleh Dec 30 '19 at 09:47
  • 1
    Read about [Reference types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types?WT.mc_id=DT-MVP-5003235). You will also fins this post useful [Value vs Reference Types](http://www.albahari.com/valuevsreftypes.aspx) – Reza Aghaei Dec 30 '19 at 09:47
  • 1
    Have a look at this link: https://stackoverflow.com/a/78612/2146626. – 4ndy Dec 30 '19 at 09:50
  • You can serialize/deserialize the object, if you just need to roll back some properties. It won't preserve States, though. Your class could implement [ICloneable](https://learn.microsoft.com/en-us/dotnet/api/system.icloneable) (though a State is hard to reproduce anyway) – Jimi Dec 30 '19 at 09:57
  • ... but it doesn't look like your class needs to preserve a State. – Jimi Dec 30 '19 at 10:06

0 Answers0