Back to Devexpress

How to: Bind an XPCollection to Standard Controls

xpo-4937-examples-how-to-bind-an-xpcollection-to-standard-controls.md

latest9.3 KB
Original Source

How to: Bind an XPCollection to Standard Controls

  • Sep 15, 2020
  • 5 minutes to read

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.

Persistent Classes Declaration

First, declare the Person and Position classes. In this sample application a person is represented by the Name and Position properties.

csharp
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); }
    }
}
vb
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.

User Interface Design and Data Binding

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”.

Saving the Persistent Objects

To save the changes made, handle the button’s Click event as shown below:

csharp
using DevExpress.Xpo;

...

private void button1_Click(object sender, EventArgs e) {
   Session ses = XpoDefault.Session;
   ses.Save(xpCollectionPersons);
   ses.Save(xpCollectionPositions);
}
vb
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

Synchronizing the Viewing and Editing Sections

To update the DataGridView control and immediately reflect the changes made, handle the TextBox’s TextChanged and ComboBox’s SelectedIndexChanged events:

csharp
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);
    }
}
vb
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

Populating the Database

To fill the database with sample data, do the following:

csharp
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();                
}
vb
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

Results

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

Property Descriptors

XPO Templates