xpo-4937-examples-how-to-bind-an-xpcollection-to-standard-controls.md
This example demonstrates how to build a simple data-aware application using standard controls. The application will be used to view and edit a person’s details using standard controls. A person’s data will be displayed in a standard DataGridView control in read-only mode. All data editing will be done via the editing section, which contains separate standard controls for each person’s property. Changes made in the corresponding editor will be immediately reflected in the DataGridView control. The changes will be persisted in a database by pressing the Save button.
First, declare the Person and Position classes. In this sample application a person is represented by the Name and Position properties.
public class Person : XPObject {
public string Name {
get { return GetPropertyValue<String>(nameof(Name)); }
set { SetPropertyValue(nameof(Name), value); }
}
public Position Position {
get { return GetPropertyValue<Position>(nameof(Position)); }
set { SetPropertyValue(nameof(Position), value); }
}
}
public class Position : XPObject {
public string PositionName {
get { return GetPropertyValue<String>(nameof(PositionName)); }
set { SetPropertyValue(nameof(PositionName), value); }
}
}
Public Class Person
Inherits XPObject
Public Property Name() As String
Get
Return GetPropertyValue(Of String)(NameOf(Name))
End Get
Set(ByVal value As String)
SetPropertyValue(NameOf(Name), value)
End Set
End Property
Public Property Position() As Position
Get
Return GetPropertyValue(Of Position)(NameOf(Position))
End Get
Set(ByVal value As Position)
SetPropertyValue(NameOf(Position), value)
End Set
End Property
End Class
Public Class Position
Inherits XPObject
Public Property PositionName() As String
Get
Return GetPropertyValue(Of String)(NameOf(PositionName))
End Get
Set(ByVal value As String)
SetPropertyValue(NameOf(PositionName), value)
End Set
End Property
End Class
Before you continue, add this code to your project and re-build it.
The viewing section contains the DataGridView control that is used to navigate through the Person objects. The editing section contains the standard Textbox and Combobox controls that are used to edit the person’s Name and Position properties. The Save button is used to save changes to a database.
To display data we use two XPCollection components provided by XPO. The first collection should contain Person objects, and the second collection should contain Position objects.
Follow the steps below to create the required collections:
Drag the XPCollection component from the toolbox and drop it onto the main form.
Rename the collection to “xpCollectionPersons”.
Assign the “Person” persistent class to the XPCollection.ObjectClassInfo property:
Drag the second XPCollection component from the toolbox and drop it onto the form.
Rename this collection to “xpCollectionPositions”.
Assign the “Position” persistent class to the ObjectClassInfo property.
To bind the controls to the collections, do the following:
Open the DataGridView’s task pane. Set the DataSource property to “xpCollectionPersons”. Uncheck the “Enable Adding”, “Enable Editing” and “Enable Deleting” options:
Invoke the Columns editor by clicking “Edit Columns…” task.
Remove the automatically generated columns except the “Name” column.
Create a new “Position” DataGridViewComboBoxColumn column.
Set its properties as follows: DataPropertyName to “Position!”, DataSource to “xpCollectionPositions”, DisplayMember to “PositionName”, ValueMember to “This”.
Bind the TextBox’s Text property to the xpCollectionPersons’ Name property:
Set the ComboBox’s DataSource property to “xpCollectionPositions”. Bind the SelectedValue property to xpCollectionPersons’ Position! property. Set the DisplayMember property to “PositionName” and the ValueMember property to “This”.
To save the changes made, handle the button’s Click event as shown below:
using DevExpress.Xpo;
...
private void button1_Click(object sender, EventArgs e) {
Session ses = XpoDefault.Session;
ses.Save(xpCollectionPersons);
ses.Save(xpCollectionPositions);
}
Imports DevExpress.Xpo
...
Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles button1.Click
Dim ses As Session = XpoDefault.Session
ses.Save(xpCollectionPersons)
ses.Save(xpCollectionPositions)
End Sub
To update the DataGridView control and immediately reflect the changes made, handle the TextBox’s TextChanged and ComboBox’s SelectedIndexChanged events:
enum refreshType {
Name,
Position
}
...
private void refreshObjects(object sender, refreshType refT) {
Person cur = (Person)(this.BindingContext[xpCollectionPersons] as CurrencyManager).Current;
switch (refT) {
case refreshType.Name:
cur.Name = (sender as TextBox).Text;
break;
case refreshType.Position:
cur.Position = (sender as System.Windows.Forms.ComboBox).SelectedValue as Position;
break;
default:
break;
}
}
private void textBox1_TextChanged(object sender, EventArgs e) {
refreshObjects(sender, refreshType.Name);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
if (comboBox1.Focused) {
refreshObjects(sender, refreshType.Position);
}
}
Private Enum refreshType
Name
Position
End Enum
...
Private Sub refreshObjects(ByVal sender As Object, ByVal refT As refreshType)
Dim cur As Person = CType((TryCast(Me.BindingContext(xpCollectionPersons), _
CurrencyManager)).Current, Person)
Select Case refT
Case refreshType.Name
cur.Name = (TryCast(sender, TextBox)).Text
Case refreshType.Position
cur.Position = TryCast((TryCast(sender, System.Windows.Forms.ComboBox)).SelectedValue, _
Position)
Case Else
End Select
End Sub
Private Sub textBox1_TextChanged(ByVal sender As Object, ByVal e As EventArgs) _
Handles textBox1.TextChanged
refreshObjects(sender, refreshType.Name)
End Sub
Private Sub comboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) _
Handles comboBox1.SelectedIndexChanged
If comboBox1.Focused Then
refreshObjects(sender, refreshType.Position)
End If
End Sub
To fill the database with sample data, do the following:
private void Form1_Load(object sender, EventArgs e) {
Position pos1 = new Position();
pos1.PositionName = "Manager";
pos1.Save();
Position pos2 = new Position();
pos2.PositionName = "Technician";
pos2.Save();
Person per1 = new Person();
per1.Name = "Bob";
per1.Position = pos1;
per1.Save();
Person per2 = new Person();
per2.Name = "John";
per2.Position = pos2;
per2.Save();
xpCollectionPersons.Reload();
xpCollectionPositions.Reload();
}
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Dim pos1 As New Position()
pos1.PositionName = "Manager"
pos1.Save()
Dim pos2 As New Position()
pos2.PositionName = "Technician"
pos2.Save()
Dim per1 As New Person()
per1.Name = "Bob"
per1.Position = pos1
per1.Save()
Dim per2 As New Person()
per2.Name = "John"
per2.Position = pos2
per2.Save()
xpCollectionPersons.Reload()
xpCollectionPositions.Reload()
End Sub
The following image illustrates the implemented application’s main form:
Run the project. It’s assumed that the database isn’t empty. Select a row in the DataGridView control and edit its data using the corresponding editors displayed within the editing section. Any changes made are immediately reflected within the DataGridView control. To save the changes to the database, press the Save button.
See Also