If you compile and run the following snippet, and then follow the steps below;
1. Click add new row (row is defaulted with values);
2. Change the value in the Status column to 4, then hit enter;
The display value for row 5 has been updated with the same values for status and review date. However the underlying datasource is correctly updated. The display is different to the underlying object.
This took a while to fathom out (Ive been working with legacy code implementing new features using the Telerik controls). The problem occurs with the fact that in our ancestor class Equals has been overriden. In the concrete classes a field called SqlKeyString is overriden and this provides a "key" for the objects to do an equality test.
It therefore looks like the RadGridView is using "Equals" rather than "==", my question is therefore should the RadGridView really be using "==" rather than "Equals"?
My 2nd issue with the gridview, is when adding a new row the CellFormatting doesnt apply to the new row. When you click a new row in this example a date with value DateTime.MinValue should be displayed as an string.Empty, however the actual value is displayed.
Thanks for your attention,
Dave
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; |
using Telerik.WinControls.UI; |
namespace TelerikDataGridView |
{ |
#region Form |
public class Form1 : Form |
{ |
public Form1() |
{ |
InitializeComponent(); |
} |
/// <summary> |
/// Required designer variable. |
/// </summary> |
private System.ComponentModel.IContainer components = null; |
/// <summary> |
/// Clean up any resources being used. |
/// </summary> |
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
protected override void Dispose(bool disposing) |
{ |
if (disposing && (components != null)) |
{ |
components.Dispose(); |
} |
base.Dispose(disposing); |
} |
#region Windows Form Designer generated code |
/// <summary> |
/// Required method for Designer support - do not modify |
/// the contents of this method with the code editor. |
/// </summary> |
private void InitializeComponent() |
{ |
this.radGridView1 = new Telerik.WinControls.UI.RadGridView(); |
((System.ComponentModel.ISupportInitialize)(this.radGridView1)).BeginInit(); |
((System.ComponentModel.ISupportInitialize)(this.radGridView1.MasterGridViewTemplate)).BeginInit(); |
this.SuspendLayout(); |
// |
// radGridView1 |
// |
this.radGridView1.Dock = System.Windows.Forms.DockStyle.Fill; |
this.radGridView1.Location = new System.Drawing.Point(0, 0); |
this.radGridView1.Name = "radGridView1"; |
this.radGridView1.Size = new System.Drawing.Size(905, 285); |
this.radGridView1.TabIndex = 0; |
// |
// Form3 |
// |
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; |
this.ClientSize = new System.Drawing.Size(905, 285); |
this.Controls.Add(this.radGridView1); |
this.Name = "Form3"; |
this.Text = "Form3"; |
((System.ComponentModel.ISupportInitialize)(this.radGridView1.MasterGridViewTemplate)).EndInit(); |
((System.ComponentModel.ISupportInitialize)(this.radGridView1)).EndInit(); |
this.ResumeLayout(false); |
} |
#endregion |
private Telerik.WinControls.UI.RadGridView radGridView1; |
protected override void OnLoad(EventArgs e) |
{ |
base.OnLoad(e); |
CreateGrid(); |
} |
private void CreateGrid() |
{ |
BindingSource source = new BindingSource(); |
source.AllowNew = true; |
source.AddingNew += new AddingNewEventHandler(source_AddingNew); |
source.DataSource = new MyCollection(); |
this.radGridView1.MasterGridViewTemplate.AutoGenerateColumns = false; |
this.radGridView1.CellFormatting += new CellFormattingEventHandler(radGridView1_CellFormatting); |
radGridView1.DataSource = source; |
AddTextColumn("FundManagerId", "Fund Manager"); |
AddTextColumn("AssetClassId", "Asset Class"); |
AddTextColumn("ClientOrgId", "Client"); |
AddTextColumn("Status", "Status"); |
AddDateColumn("ReviewDate", "Review Date", true); |
radGridView1.MasterGridViewTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; |
} |
void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e) |
{ |
if (e.CellElement is GridDateTimeCellElement) |
{ |
GridDateTimeCellElement cell = e.CellElement as GridDateTimeCellElement; |
if (cell.IsEditMode) |
return; |
if (((DateTime)cell.Value).Equals(DateTime.MinValue)) |
cell.Text = string.Empty; |
else |
cell.Text = string.Format("{0:dd/MM/yyyy}", (DateTime)cell.Value); |
} |
} |
int assetClass = 5; |
void source_AddingNew(object sender, AddingNewEventArgs e) |
{ |
e.NewObject = new MyClass(12, 5, assetClass++, 2, DateTime.MinValue); |
} |
private void AddTextColumn(string field, string header) |
{ |
AddTextColumn(field, header, false); |
} |
private void AddTextColumn(string field, string header, bool readOnly) |
{ |
GridViewTextBoxColumn column = new GridViewTextBoxColumn(field); |
column.HeaderText = header; |
column.ReadOnly = readOnly; |
radGridView1.MasterGridViewTemplate.Columns.Add(column); |
} |
private void AddDateColumn(string field, string header) |
{ |
AddDateColumn(field, header, false); |
} |
private void AddDateColumn(string field, string header, bool readOnly) |
{ |
GridViewDateTimeColumn dateColumn = new GridViewDateTimeColumn(); |
dateColumn.BestFit(); |
dateColumn.FieldName = field; |
dateColumn.FormatString = "{0:dd/MM/yyyy}"; |
dateColumn.HeaderText = header; |
dateColumn.ReadOnly = readOnly; |
dateColumn.TextAlignment = ContentAlignment.MiddleCenter; |
radGridView1.MasterGridViewTemplate.Columns.Add(dateColumn); |
} |
} |
#endregion |
#region DataSources |
public class MyClass : InvestmentObject |
{ |
public MyClass(int client, int fundManager, int assetClass, int status, DateTime statusDate) |
{ |
FundManagerId = fundManager; |
AssetClassId = assetClass; |
ClientOrgId = client; |
ReviewDate = statusDate; |
Status = status; |
} |
public MyClass(int client, int fundManager, int assetClass) |
: this(client, fundManager, assetClass, 1, DateTime.Now) |
{ |
} |
private int _fundManagerId; |
public int FundManagerId |
{ |
get { return _fundManagerId; } |
set |
{ |
_fundManagerId = value; |
OnPropertyChanged("FundManagerId"); |
} |
} |
private int _assetClassId; |
public int AssetClassId |
{ |
get { return _assetClassId; } |
set |
{ |
_assetClassId = value; |
OnPropertyChanged("AssetClassId"); |
} |
} |
private int _clientOrgId; |
public int ClientOrgId |
{ |
get { return _clientOrgId; } |
set |
{ |
_clientOrgId = value; |
OnPropertyChanged("ClientOrgId"); |
} |
} |
private int _status; |
public int Status |
{ |
get { return _status; } |
set |
{ |
_status = value; |
OnPropertyChanged("Status"); |
} |
} |
private DateTime _reviewDate; |
public DateTime ReviewDate |
{ |
get { return _reviewDate; } |
set |
{ |
_reviewDate = value; |
OnPropertyChanged("ReviewDate"); |
} |
} |
public override string SqlKeyString |
{ |
get |
{ |
return string.Format("FundManagerId={0} and AssetClassId={1} and ClientOrgId={2}" |
, FundManagerId, AssetClassId, ClientOrgId); |
} |
} |
} |
public class MyCollection : DataList<MyClass> |
{ |
public MyCollection() |
{ |
Add(new MyClass(12, 5, 1)); |
Add(new MyClass(12, 5, 2)); |
Add(new MyClass(12, 5, 3)); |
Add(new MyClass(12, 5, 4)); |
Add(new MyClass(12, 5, 5)); |
} |
} |
#endregion |
#region Supporting Data Objects |
public abstract class DataList<T> : BindingList<T> |
{ |
public void Sort(Comparison<T> comparer) |
{ |
((List<T>)this.Items).Sort(comparer); |
} |
public void Sort(IComparer<T> comparer) |
{ |
((List<T>)this.Items).Sort(comparer); |
} |
} |
public abstract class InvestmentObject : INotifyPropertyChanged |
{ |
#region Private Fields |
private DateTime lastModified; |
private Guid guid; |
#endregion |
#region Constructors |
protected InvestmentObject() |
: base() |
{ |
lastModified = DateTime.Now; |
guid = Guid.NewGuid(); |
} |
#endregion |
#region Data Properties |
public DateTime LastModified |
{ |
get { return lastModified; } |
protected set { lastModified = value; } |
} |
public Guid CurrentGUID |
{ |
get { return guid; } |
protected set { guid = value; } |
} |
#endregion |
public override bool Equals(object obj) |
{ |
if ((obj != null) && (obj.GetType() == this.GetType())) |
{ |
InvestmentObject dataAccessObject = obj as InvestmentObject; |
return (dataAccessObject.SqlKeyString == this.SqlKeyString); |
} |
else return false; |
} |
public override int GetHashCode() |
{ |
return (this.GetType().ToString() + SqlKeyString).GetHashCode(); |
} |
#region Abstract |
public abstract string SqlKeyString { get; } |
#endregion |
#region INotifyPropertyChanged Members |
public event PropertyChangedEventHandler PropertyChanged; |
protected virtual void OnPropertyChanged(string field) |
{ |
if (PropertyChanged != null) |
PropertyChanged(this, new PropertyChangedEventArgs(field)); |
} |
#endregion |
} |
#endregion |
} |