2

I have a client application that downloads a number of STE's via WCF.

Using a WPF application, users can select an entity from a ListBox, and edit it via a popup UserControl. As the UserControl is bound directly to the object, when a user makes a change it of course affects the object.

I would like to provide a Cancel function which will undo all changes made to the entity.

Any thoughts?

mortware
  • 1,910
  • 1
  • 20
  • 35

4 Answers4

3

You can keep a original copy of the entity. And edit a cloned version of it.
If the user cancels the changes you simply keep using the original copy.

Tocco
  • 1,655
  • 11
  • 14
  • This is the way I follow as well. And it's probably the only option. Because a STE doesn't keep track of all original values (as normal EF entities do) which you else could set back. Only the primary / foreign key properties are tracked in the original values dictionary (of the ChangeTracker) – Youp Bernoulli Jul 08 '11 at 21:20
  • So when I want to save the new changes, simply persisting the cloned object back up the wire will work? – mortware Jul 08 '11 at 22:11
  • 1
    Yes. That will work. Clone the entity. Keep the original or the clone as a backup (doesn't matter real much) when the user edits the entity, the changetracker will do it's work (commonly in a databinding scenario) and you can send the cloned entity over the wire to be persisted through an objectcontext (.ApplyChanges; .SaveChanges). When the users cancel it's action you go on using the backup of the entity you cloned before editing operations where taking place. – Youp Bernoulli Jul 09 '11 at 08:19
3

I would say as you use WPF just in binded PropertyChanged event save a Dictionary with key PropertyName and value PropertyValue. And after restore the state by using reflection

Tigran
  • 61,654
  • 8
  • 86
  • 123
2

I'm using this solution so far Extension method

using System.Collections.Generic;
using System.Reflection;

namespace WpfApplication4
{
    public static class EFExtensions
    {
        /// <summary>
        /// Rejects changes made by user
        /// </summary>
        /// <param name="param">Object implementing IObjectWithChangeTracker interface</param>
        public static void RejectChanges(this IObjectWithChangeTracker param)
        {
            OriginalValuesDictionary ovd = param.ChangeTracker.OriginalValues;
            PropertyInfo[] propertyInfos = (param.GetType()).GetProperties();

            foreach (KeyValuePair<string, object> pair in ovd)
            {
                foreach (PropertyInfo property in propertyInfos)
                {
                    if (property.Name == pair.Key && property.CanWrite)
                    {
                        property.SetValue(param, pair.Value, null);
                    }
                }
            }
        }
    }
}

Main code

using System.Linq;

namespace WpfApplication4
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();

            using (var db = new PlatEntities())
            {
                PacketEPD pd = (from epd in db.PacketEPD
                                select epd).First();
                pd.ChangeTracker.ChangeTrackingEnabled = true;
                pd.EDNo = "1";
                pd.RejectChanges();
            }
        }
    }
}
Pavel Kovalev
  • 7,521
  • 5
  • 45
  • 67