可以把 XtraGrid 绑定到不支持更改通知的数据源。 但是,当修改这种数据源中的数据时,XtraGrid 不会接收到任何更改通知,因此不能反映对数据所作出的更改。 在这种情况下,如果要使用数据源中的数据来同步网格控件,则需要人工更新网格控件。 另一方面,如果数据源 实现了 IBindingList 接口,则网格控件始终可以感知对数据源作出的任何更改。 另外,如果只使用由视图提供的方法来修改任何类型的绑定数据源,则不需要人工更新网格控件。 获取和设置单元格的值 文档描述了如何使用由视图提供的方法来更改取值。
刷新网格控件
如果只更新一个特定的视图,则使用 BaseView.RefreshData 方法。
下列代码假设网格控件的数据源是一个 Record 对象的数组。 当修改记录的“Phone”字段时,调用了 GridControl.RefreshDataSource 方法来反映在网格控件中的更改。
C# | 复制代码 |
---|---|
public class Record { //... public Record(string name, string phone) {...} public string Name {...} public string Phone {...} } private void Form1_Load(object sender, System.EventArgs e) { Record[] records = {new Record("Alex Cooper", "123-456"), new Record("Alicia Walker", "123-764") }; //Bind the grid control gridControl1.DataSource = records; } private void button1_Click(object sender, System.EventArgs e) { ColumnView View = gridControl1.MainView as ColumnView; int rowHandle = View.FocusedRowHandle; //Check if the focused record is a group row, if so exit if (rowHandle < 0) return; //Get the row by its handle Record row = View.GetRow(rowHandle) as Record; //Change the Phone field via the bound data source row.Phone = "765-123"; //Refresh the grid control gridControl1.RefreshDataSource(); } |
Visual Basic | 复制代码 |
---|---|
Public Class Record '... Public Sub New(ByVal name As String, ByVal phone As String) '... End Sub Public Property Name() As String '... End Property Public Property Phone() As String '... End Property End Class Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load Dim records As Record() = {New Record("Alex Cooper", "123-456"), _ New Record("Alicia Walker", "123-764") _ } 'Bind the grid control GridControl1.DataSource = records End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click Dim View As ColumnView = CType(GridControl1.MainView, ColumnView) Dim rowHandle As Integer = View.FocusedRowHandle 'Check if the focused record is a group row, if so exit If rowHandle < 0 Then Return 'Get the row by its handle Dim row As Record = View.GetRow(rowHandle) 'Change the Phone field via the bound data source row.Phone = "765-123" 'Refresh the grid control GridControl1.RefreshDataSource() End Sub |
如果被绑定到支持更改通知的数据源,则不需要调用网格控件的 GridControl.RefreshDataSource 方法来更新它 (例如 DataView 支持更改通知)。 这种数据源引发更改事件,这样网格控件始终使用绑定数据源进行同步。
实现通知行为
GridControl.RefreshDataSource 方法需要耗用一些时间来执行,特别是在为视图应用了分组或排序的时候。 如果数据源不支持更改通知,而必须通过由数据源提供的方法来修改数据,则可以考虑实现 IBindingList 接口。 如果数据源实现了此接口,则网格控件自动订阅 ListChanged 事件,这能确保在添加、删除、移动或修改记录时,它能接收适当的更改通知。
下面是一个来源于 IBindingList 指南的示例。 为 Records 类实现了 IBindingList 接口,此类是 Record 对象的集合。 只要记录被添加、插入或移除, ListChanged 事件就会发生,此事件提供了所作更改的细节。 为了达到此目的, CollectionBase.OnInsertComplete 和 CollectionBase.OnRemoveComplete 方法被重写。
每个 Record 对象都能通知它的所有者。 当 Record 对象的任何属性被修改时,它的所有者的 ListChanged 事件也会发生。
如果把 Records 的一个实例指派到 GridControl.DataSource,则通过数据源修改记录时,网格控件将自动接收所有更改通知。 完整的代码可以在 IBindingList 指南中找到。
C# | 复制代码 |
---|---|
// The collection of Record objects which supports change notifications. public class Records : CollectionBase, IBindingList { private ListChangedEventHandler listChangedHandler; public event ListChangedEventHandler ListChanged { add { listChangedHandler += value; } remove { listChangedHandler -= value; } } // Fire the ListChanged event. internal void OnListChanged(ListChangedEventArgs args) { if (listChangedHandler != null) { listChangedHandler(this, args); } } // The method is called when a Record is removed from the collection. protected override void OnRemoveComplete(int index, object value) { OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index) ); } // The method is called after a new Record is added or inserted. protected override void OnInsertComplete(int index, object value) { OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index) ); } // Implement other methods. public void Add(Record record) { base.List.Add(record); } public Record this[int idx] { get { return (Record) base.List[idx]; } } public void AddIndex(PropertyDescriptor pd) { throw new NotSupportedException(); } // ... } // The class representing an item for the Records collection public class Record : IEditableObject { private string name; private DateTime date; // The owner. private Records records; public Record(Records records) { this.records = records; this.date = DateTime.Now; } // Invoke the ListChanged event for the owner. private void OnListChanged() { int index = records.IndexOf(this); records.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index)); } public string Name { get { return name; } set { name = value; OnListChanged(); } } public DateTime PurchaseDate { get { return date; } set { date = value; OnListChanged(); } } // ... } |
Visual Basic | 复制代码 |
---|---|
' The collection of Record objects which supports change notifications. Public Class Records Inherits CollectionBase Implements IBindingList Public Event ListChanged As ListChangedEventHandler Implements IBindingList.ListChanged ' Fire the ListChanged event. Friend Sub OnListChanged(ByVal args As ListChangedEventArgs) RaiseEvent ListChanged(Me, args) End Sub ' The method is called when a Record is removed from the collection. Protected Overrides Sub OnRemoveComplete(ByVal index As Integer, ByVal value As Object) OnListChanged(New ListChangedEventArgs(ListChangedType.ItemDeleted, index)) End Sub ' The method is called after a new Record is added or inserted. Protected Overrides Sub OnInsertComplete(ByVal index As Integer, ByVal value As Object) OnListChanged(New ListChangedEventArgs(ListChangedType.ItemAdded, index)) End Sub ' Implement other methods. Public Sub Add(ByVal _record As Record) MyBase.List.Add(_record) End Sub Sub AddIndex(ByVal prop As PropertyDescriptor) Implements IBindingList.AddIndex Throw New NotSupportedException End Sub End Class ' The class representing an item for the Records collection. Public Class Record Implements IEditableObject Private _name As String Private _date As DateTime ' The owner. Private _records As Records Public Sub New(ByVal _records As Records) Me._records = _records Me._date = DateTime.Now End Sub ' Invoke the ListChanged event for the owner. Private Sub OnListChanged() Dim index As Integer = _records.IndexOf(Me) _records.OnListChanged(New ListChangedEventArgs(ListChangedType.ItemChanged, index)) End Sub Public Property PurchaseDate() As DateTime Get Return _date End Get Set(ByVal Value As DateTime) _date = Value OnListChanged() End Set End Property ' ... End Class |