xpo-3259-examples-how-to-make-xpcollection-create-objects-of-specific-type-when-they-are-created-via-bound-controls.md
In certain scenarios, a collection may be designed to hold objects of derived types, but must be base-typed. To simplify working in such scenarios, the XPCollection provides a way to create derived-type objects via bound controls when the collection itself is base-typed.
To make a collection create objects of a specific type, derive from the XPCollection class, and override the protected virtual XPBaseCollection. CreateAddNewInstance method, to return an object of the required type. This method is automatically called, for example, when the Append button of the Grid control’s embedded data navigator is clicked.
The following code snippets illustrate this. The sample Windows Forms application has two business classes defined - the BaseClass and DerivedClass :
using DevExpress.Xpo;
//...
public class BaseClass : XPObject {
public BaseClass(Session session) : base(session) { }
public string BaseField {
get { return fBaseField; }
set { SetPropertyValue(nameof(BaseField), ref fBaseField, value); }
}
string fBaseField;
}
public class DerivedClass : BaseClass {
public DerivedClass(Session session) : base(session) { }
public string DerivedField {
get { return fDerivedField; }
set { SetPropertyValue(nameof(DerivedField), ref fDerivedField, value); }
}
string fDerivedField;
}
Imports DevExpress.Xpo
'...
Public Class BaseClass
Inherits XPObject
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Property BaseField() As String
Get
Return fBaseField
End Get
Set(ByVal value as String)
SetPropertyValue(NameOf(BaseField), fBaseField, value)
End Set
End Property
Private fBaseField As String
End Class
Public Class DerivedClass
Inherits BaseClass
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Property DerivedField() As String
Get
Return fDerivedField
End Get
Set(ByVal value as String)
SetPropertyValue(NameOf(DerivedField), fDerivedField, value)
End Set
End Property
Private fDerivedField As String
End Class
The application contains a single Form1 form. On the form there is the gridControl1 XtraGrid control with the enabled data navigator. The XtraGrid control is bound to a MyXPCollection<BaseClass> -type collection, which derives from the XPCollection<BaseClass>. The derived collection has the CreateAddNewInstance method overridden, to return a new DerivedClass -type object:
using DevExpress.Xpo;
//...
public class MyXPCollection<BaseClass> : XPCollection<BaseClass> {
public MyXPCollection(Session session) : base(session) { }
protected override object CreateAddNewInstance() {
return new DerivedClass(Session);
}
}
//...
public partial class Form1 : Form {
//...
private void Form1_Load(object sender, EventArgs e) {
//...
Session MySession = new Session();
MyXPCollection<BaseClass> xpCollection =
new MyXPCollection<BaseClass>(MySession);
gridControl1.DataSource = xpCollection;
}
}
Imports DevExpress.Xpo
'...
Public Class MyXPCollection(Of BaseClass)
Inherits XPCollection(Of BaseClass)
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Protected Overrides Function CreateAddNewInstance() As Object
Return New DerivedClass(Session)
End Function
End Class
'...
Partial Public Class Form1
Inherits Form
'...
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
'...
Dim MySession As New Session()
Dim xpCollection As MyXPCollection(Of BaseClass) = _
New MyXPCollection(Of BaseClass)(MySession)
gridControl1.DataSource = xpCollection
End Sub
End Class
So, the collection is BaseClass -typed, but objects created via the XtraGrid control’s embedded data navigator will be DerivedClass -typed.