WPF数据绑定-处理用户取消

时间:2018-08-03 05:38:10

标签: c# wpf data-binding

因此,我有一个可以大量使用数据绑定的应用程序。该应用程序的一个功能是一个弹出窗口,允许用户管理一些记录。他们从列表框中选择一条记录,然后使用表单来编辑该记录的对象实例的属性。

用户通常习惯于在表格末尾选择“保存”或“取消”。保存将提交更改,而“取消”放弃更改。

但是,通过双向数据绑定,随着字段值的更改,对象将实时更新。

在WPF中是否存在通过数据绑定处理Commit / Cancel行为的“最佳实践”方法?我曾考虑过克隆要编辑的对象,以便在该克隆上进行更改,然后“保存”将更改应用于原始记录,但是我感觉这可能是Microsoft已经内置的东西,我只是不知道如何正确使用它。

1 个答案:

答案 0 :(得分:0)

WPF提供BindingGroup来处理您遇到的情况。 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Linq.Expressions; namespace EntityFrameworkRepositoryPatternTestApp { public class Item { public Guid Id { get; set; } public string SomeString { get; set; } public int SomeInt { get; set; } public double SomeDouble { get; set; } } public class Context : DbContext { public DbSet<Item> Items { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new ItemConfiguration()); base.OnModelCreating(modelBuilder); } public Context() : base("Connection") { } } public class ItemConfiguration : EntityTypeConfiguration<Item> { public ItemConfiguration() { this.ToTable("Items").HasKey(i => i.Id); this.Property(i => i.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); this.Property(i => i.SomeString).HasMaxLength(255); this.Property(i => i.SomeInt); this.Property(i => i.SomeDouble); } } public interface IRepository<T> { T Add(T item); IEnumerable<T> Get(Expression<Func<T, bool>> filter = null); T GetById(Guid id); void Remove(T item); } public class EntityFrameworkRepository<TEntity> : IRepository<TEntity> where TEntity : class { private readonly IDbSet<TEntity> dbSet; private Context Context { get; } public TEntity Add(TEntity item) { this.dbSet.Add(item); return item; } public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null) { IQueryable<TEntity> query = this.dbSet; if (filter != null) query = query.Where(filter); return query.ToList(); } public TEntity GetById(Guid id) { return this.dbSet.Find(id); } public void Remove(TEntity item) { this.dbSet.Remove(item); } public EntityFrameworkRepository(Context context) { this.Context = context; this.dbSet = this.Context.Set<TEntity>(); } } public interface IDomainContext { int SaveChanges(); int SaveChangesWithoutClientValidation(); } public interface IDomainContext<TEntity> : IDomainContext where TEntity : class { IRepository<TEntity> Entities { get; } void Update(TEntity item); void Attach(TEntity item); void Detach(TEntity item); } public class DomainContext<TEntity> : IDomainContext<TEntity>, IDisposable where TEntity : class { private Context context; public int SaveChanges() { return this.context.SaveChanges(); } public IRepository<TEntity> Entities => this.GetRepository<TEntity>(); public void Update(TEntity item) { var entry = this.context.Entry(item); foreach (var propertyName in entry.OriginalValues.PropertyNames) { var original = entry.OriginalValues.GetValue<object>(propertyName); var current = entry.CurrentValues.GetValue<object>(propertyName); if ((original == null && current != null) || ((original != null) && !original.Equals(current))) entry.Property(propertyName).IsModified = true; } } public void Attach(TEntity item) => this.context.Set<TEntity>().Attach(item); public void Detach(TEntity entity) => ((IObjectContextAdapter)this.context).ObjectContext.Detach(entity); public void Dispose() { this.context.Dispose(); } private IRepository<T> GetRepository<T>() where T : class { var resultRepository = new EntityFrameworkRepository<T>(this.context); return resultRepository; } public DomainContext() { this.context = new Context(); } } public class Program { static void Main(string[] args) { var domainContext = new DomainContext<Item>(); { var item = new Item() { Id = Guid.NewGuid(), SomeDouble = 666, SomeInt = 777, SomeString = "some string"}; domainContext.Entities.Add(item); domainContext.SaveChanges(); using (var domainContext2 = new DomainContext<Item>()) { if (item != null) { domainContext2.Attach(item); item.SomeDouble = 11.28; domainContext2.Update(item); domainContext2.SaveChanges(); } } } domainContext.Dispose(); } } } 允许您同时处理多个值更改。您可以基于同时验证所有更改的结果来提交或取消更改,而不仅要分别验证每个更改。为了使编辑事务正常工作,BindingGroup中的源应实现IEditableObject接口。