Windows Forms binding allows you to discard changes made in a data item (row/record). This feature is available for data objects that implement IEditableObject (CurrencyManager.CancelCurrentEdit).
Entity Framework 4 comes with POCO support that allows developers to define entities (base classes are not required). By not inheriting from the underlying entities of the framework, developers lost the built-in implementations of IEditableObject
and INotifyPropertyChanged
interfaces (for example, the capability to undo changes to a grid control if data validation fails).
This example demonstrates how to address this issue at the GridView level. The example creates a custom Grid View. The custom GridView uses a new data controller (inherited from the CurrencyDataController
class) and overrides the following methods: BeginCurrentRowEdit
, EndCurrentRowEdit
, and CancelCurrentRowEdit
.
Files to Review
- Form1.cs (VB: Form1.vb)
- CancellingChangesDataController.cs (VB: CancellingChangesDataController.vb)
- GridControlEx.cs (VB: GridControlEx.vb)
- GridViewEx.cs (VB: GridViewEx.vb)
- GridViewExInfoRegistrator.cs (VB: GridViewExInfoRegistrator.vb)
- GridViewExOptionsBehavior.cs (VB: GridViewExOptionsBehavior.vb)
- Person.cs (VB: Person.vb)
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using DevExpress.Utils;
using DevExpress.XtraGrid.Views.Base;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DxSample {
public partial class Form1 :Form {
public Form1() {
InitializeComponent();
}
private void OnValidateRow(object sender, ValidateRowEventArgs e) {
Person p = (Person)e.Row;
e.Valid = string.IsNullOrEmpty(p.Name) || p.Name.Contains("A");
}
}
}
C#using DevExpress.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace DxSample.Grid {
public class CancellingChangesDataController :CurrencyDataController {
class ColumnValuePair {
public DataColumnInfo Column { get; set; }
public object Value { get; set; }
public void Free() {
Column = null;
Value = null;
}
}
List<ColumnValuePair> originalValues = new List<ColumnValuePair>();
public bool CanCancelChanges { get; set; }
bool ShouldCancelChanges {
get { return CanCancelChanges && CurrentControllerRow != NewItemRow && !(CurrentControllerRowObject is IEditableObject); }
}
public override void BeginCurrentRowEdit() {
base.BeginCurrentRowEdit();
if (ShouldCancelChanges && originalValues.Count == 0)
foreach (DataColumnInfo col in Columns)
originalValues.Add(new ColumnValuePair() { Column = col, Value = GetCurrentRowValue(col) });
}
public override bool EndCurrentRowEdit(bool force) {
bool result = base.EndCurrentRowEdit(force);
if (result) {
foreach (ColumnValuePair val in originalValues)
val.Free();
originalValues.Clear();
}
return result;
}
public override void CancelCurrentRowEdit() {
base.CancelCurrentRowEdit();
foreach (ColumnValuePair val in originalValues) {
SetCurrentRowValue(val.Column, val.Value);
val.Free();
}
originalValues.Clear();
}
public override void Dispose() {
foreach (ColumnValuePair val in originalValues)
val.Free();
originalValues.Clear();
base.Dispose();
}
}
}
C#using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Registrator;
namespace DxSample.Grid {
public class GridControlEx :GridControl {
protected override void RegisterAvailableViewsCore(InfoCollection collection) {
base.RegisterAvailableViewsCore(collection);
collection.Add(new GridViewExInfoRegistrator());
}
}
}
C#using DevExpress.Data;
using DevExpress.Utils.Controls;
using DevExpress.Utils.Serializing;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using System;
using System.ComponentModel;
namespace DxSample.Grid {
public class GridViewEx :GridView {
public GridViewEx() : base() { }
public GridViewEx(GridControl ownerGrid) : base(ownerGrid) { }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), XtraSerializableProperty(XtraSerializationVisibility.Content)]
public new GridViewExOptionsBehavior OptionsBehavior {
get { return (GridViewExOptionsBehavior)base.OptionsBehavior; }
}
protected override ColumnViewOptionsBehavior CreateOptionsBehavior() {
return new GridViewExOptionsBehavior(this);
}
protected override BaseGridController CreateDataController() {
if (requireDataControllerType == DataControllerType.Regular)
return new CancellingChangesDataController();
return base.CreateDataController();
}
protected override string OnCreateLookupDisplayFilter(string text, string displayMember) {
throw new NotSupportedException("This view cannot be used in lookup editors");
}
protected override void UpdateDataControllerOptions() {
base.UpdateDataControllerOptions();
CancellingChangesDataController controller = DataController as CancellingChangesDataController;
if (controller != null)
controller.CanCancelChanges = OptionsBehavior.CanCancelChanges;
}
}
}
C#using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Registrator;
using DevExpress.XtraGrid.Views.Base;
namespace DxSample.Grid {
public class GridViewExInfoRegistrator :GridInfoRegistrator {
public override string ViewName {
get { return "GridViewEx"; }
}
public override BaseView CreateView(GridControl grid) {
return new GridViewEx(grid);
}
}
}
C#using DevExpress.Utils.Controls;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using System.ComponentModel;
namespace DxSample.Grid {
public class GridViewExOptionsBehavior :GridOptionsBehavior {
public GridViewExOptionsBehavior() : base() { }
public GridViewExOptionsBehavior(ColumnView view) : base(view) { }
bool fCanCancelChanges;
[DefaultValue(false)]
public bool CanCancelChanges {
get { return fCanCancelChanges; }
set {
if (fCanCancelChanges == value) return;
bool prevValue = CanCancelChanges;
fCanCancelChanges = value;
OnChanged(new BaseOptionChangedEventArgs("CanCancelChanges", prevValue, CanCancelChanges));
}
}
public override void Assign(BaseOptions options) {
BeginUpdate();
try {
base.Assign(options);
GridViewExOptionsBehavior opt = options as GridViewExOptionsBehavior;
if (opt == null) return;
fCanCancelChanges = opt.CanCancelChanges;
} finally { EndUpdate(); }
}
}
}