-1

I am writing a WPF page to update data stored on an SQL server, and the way I am writing it requires a copy of the original data to be stored to create a WHERE clause.
So, what I am trying to do is have two copies of the data stored in variables on the page. One that remains as the original object and one that is to be used as the data binding context which are declared like so:

public Object Current { get; set; }
private readonly Object Start = new Object();

Which in my constructor are declared as:

public PageUpdate(Object source) {
    InitializeComponent();
    Current = source;
    Start = source;
}

If my understanding of data binding is correct, the data binding should be entirely unable to see the Start object. I have tried several approaches, including setting the data context with DataContext = Current;, using XAML to describe it in two different ways:

<TextBox x:Name="TextBox1" Text="{Binding Object.ObjectTextProperty, RelativeSource={RelativeSource FindAncestor AncestorType=Page}" />
<Page d:DataContext="{d:DesignInstance Type=Object}">
    <TextBox x:Name="TextBox1" Text="{Binding ObjectTextProperty}" />
</Page>

And finally attempted to set each binding property in code-behind:

TextBox1.SetBinding(TextBox.TextProperty, new Binding("ObjectTextProperty")
    {
        BindingGroupName = "bindingGroup",
        Source = Current,
        Mode = BindingMode.TwoWay
    });

And various combinations of the above.

Each time I've used this, I've tested by printing Start and Current to the debug console after editing the data from the front end and it always shows both objects as identical even though as far as I know, Start should never be altered by the data binding.

Am I missing something obvious here or should I just take a different approach?

Swyfte
  • 43
  • 8
  • Have a look at the IEditableObject interface. It plays nicely with MVVM and WPF DataBinding: https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.ieditableobject?view=net-5.0 Also: https://stackoverflow.com/questions/4410327/ieditableobject-in-mvvm – Emond Nov 01 '21 at 10:21
  • 2
    What objects are you assigning actually to Start and Current? I assume it is a reference type in which case you wouldn't get a copy of your object so altering a property will be reflected in both variables. – Steeeve Nov 01 '21 at 10:28
  • @Steeeve I just edited the question to show the constructor where both things are assigned. The object is copied from another page which has an ObservableCollection, the only item changed is the one opened on the Update page somehow. – Swyfte Nov 01 '21 at 10:34
  • So what is the actual type of the object? Does it support something like cloning? Otherwise yo will have two references pointing to the same object. – Steeeve Nov 01 '21 at 10:38
  • @Steeeve That would explain a lot... I'll have to look up cloning. The object is a custom thing I've created myself. – Swyfte Nov 01 '21 at 10:44

1 Answers1

0

It turned out that what I needed to do was implement the ICloneable interface on Object and then simply clone the object.

I added the following to my Object class:

public class Object : ICloneable
{
    public object Clone()
    {
        return MemberWiseClone();
    }
}

And then I made the following change to my page constructor:

public PageUpdate(Object source) {
    InitializeComponent();
    Current = source;
    Start = (Object)source.Clone();
}

I hope this helps anyone else who has this problem.

Thanks to Steeeve for the solution.

Swyfte
  • 43
  • 8
  • A note: MemberwiseClone returns a shallow copy of your class. If your class has only value-type properties, it is fine. But if you have any property of a reference type, you'll need to clone them, not only the reference to them. – Steeeve Nov 01 '21 at 11:20