0

Hi i'm experimenting with databinding and have some strange things going on here. I have a MainWindow and a VarAssignmentWindow. I also have a Dictionary where my Data is stored:

public Dictionary<String, MDevice> devices = new Dictionary<string,MDevice>();

In the VarAssignmentWindow i want to change some values inside of the devices-Object if i click on an OK button, or do not apply the changes if i hit the Cancel button.

I call the VarAssignmentWindow this way:

        VarAssignmentWindow window = new VarAssignmentWindow(devices);
        window.Owner = this;
        window.ShowDialog();

        if (window.canceled == false)
        {
            //Save changes if OK was clicked
            devices = window.devices;
        }

as you can see i want to overwrite the MainWindow.devices with VarAssignmentWindow.devices if i hit the OK button, otherwhise nothing should happen.

Now here is whats going on inside of the VarAssignmentWindow class:

    public Dictionary<String, MDevice> devices = new Dictionary<string,MDevice>();
    public bool canceled = true;

    public VarAssignmentWindow(Dictionary<String, MDevice> devices)
    {
        InitializeComponent();
        this.devices = devices; //This seems to be ByRef, but only, if i bind the items to the listbox
        updateListBox();
    }

    private void updateListBox()
    {
        lstVars.Items.Clear();
        foreach (var dev in devices)
        {
            foreach (var vari in dev.Value.savedVarDic)
            {
                lstVars.Items.Add(vari.Value);
            }
        }
    }

    private void cmdOK_Click(object sender, RoutedEventArgs e)
    {
        canceled = false;
        this.Close();
    }

    private void cmdCancel_Click(object sender, RoutedEventArgs e)
    {
        canceled = true;
        this.Close();
    }

If i change anything inside the ListBox, its always changed in the MainWindow.devices object too, no matter if i hit cancel or ok.

To be sure if its a ByRef i made the following test:

    public VarAssignmentWindow(Dictionary<String, MDevice> devices)
    {
        InitializeComponent();
        this.devices = devices;
        updateListBox();
        this.devices = null;
    }
    --> devices in MainWindow is null afterwards

    public VarAssignmentWindow(Dictionary<String, MDevice> devices)
    {
        InitializeComponent();
        this.devices = devices;
        //updateListBox();
        this.devices = null;
    }
    --> devices in MainWindow is not null (its what it was before)

Is it just a stupid DataBinding mistake i made? please help!

Stefan
  • 528
  • 4
  • 12

1 Answers1

2

No, data binding does not change an object argument to ByRef. You are editing the same devices collection from your MainWindow control. Make a deep copy of the collection before passing it to your VarAssignmentWindow Window. In this way, if the user wants to cancel, you can simply return the original collection and if they save, then you return the new, edited collection.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • you say i edit the _same_ devices, when i change inside `VarAssignmentWindow` this.devices, so this.devices is just a pointer to `MainWindow.devices`? And wouldnt this be ByRef? Or do you just mean data binding doesnt change because this kind of argument is always ByRef anyway? – Stefan Jan 22 '14 at 14:01
  • Your second sentence... all objects are passed by reference anyway. You pass the actual object here: `new VarAssignmentWindow(devices);`. Instead of this, try something more like this: `new VarAssignmentWindow(copyOfDevices);`. Clearly though, *you* have to create the `copyOfDevices` clone. – Sheridan Jan 22 '14 at 14:09
  • i used [Alex Burtsev's](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically) DeepCopy solution which works great, thank you for filling my knowledge gap (i thought objects are always ByRef but my second experiment fooled me a bit (the last piece of code)) and i still dont know why the devices is not null in the mainwindow class at the last example – Stefan Jan 22 '14 at 14:29
  • Objects *are* always passed by reference... only `struct`s are passed by value. – Sheridan Jan 22 '14 at 14:42
  • yes but why in my last example devices in `MainWindow` != null? – Stefan Jan 22 '14 at 14:53
  • Sorry, I can't help with that... it *should* be `null`. – Sheridan Jan 22 '14 at 15:00