Multiple Selection. Getting Started

A simple abstract task was formulated in the Multiple Selection topic. This topic describes how to implement this task using ObjectSet<T> class. Create a test XAF-application (Win) for the demonstration. Name it ObjectSetSample.

Follow the steps described below.

  • Add XafariModule and XafariBCModule to the ObjectSetSample.Module Project.
  • Add module XafariBCWinModule to ObjectSetSample.Module.Win Project.
  • Determine the persistent classes Object_A, Object_В, Object_С . Use the code below:
  • c#
  • VB

public class Object_B : BaseObject
{
  public Object_B(Session session)
    : base(session)
  {
  }
  private string _name;
  public string Name
  {
    get
    {
      return _name;
    }
    set
    {
      SetPropertyValue("Name", ref _name, value);
    }
  }
}
public class Object_C : BaseObject
{
  public Object_C(Session session)
    : base(session)
  {
  }
  private string _name;
  public string Name
  {
    get
    {
      return _name;
    }
    set
    {
      SetPropertyValue("Name", ref _name, value);
    }
  }
}
[DefaultClassOptions]
public class Object_A : BaseObject
{
  public Object_A(Session session)
    : base(session)
  {
  }
  private string _name;
  public string Name
  {
    get
    {
      return _name;
    }
    set
    {
      SetPropertyValue("Name", ref _name, value);
    }
  }
  public Object_B Object_B
  {
    get
    {
      return this.GetPropertyValue<Object_B>("Object_B");
    }
    set
    {
      this.SetPropertyValue("Object_B", value);
    }
  }
  public Object_C Object_C
  {
    get
    {
      return this.GetPropertyValue<Object_C>("Object_C");
    }
    set
    {
      this.SetPropertyValue("Object_C", value);
    }
  }
}

Public Class Object_B
  Inherits BaseObject
  Public Sub New(ByVal session As Session)
    MyBase.New(session)
  End Sub
  Private __name As String
  Public Property Name As String
    Get
      Return __name
    End Get
    Set
      SetPropertyValue("Name", __name, value)
    End Set
  End Property
End Class
Public Class Object_C
  Inherits BaseObject
  Public Sub New(ByVal session As Session)
    MyBase.New(session)
  End Sub
  Private __name As String
  Public Property Name As String
    Get
      Return __name
    End Get
    Set
      SetPropertyValue("Name", __name, value)
    End Set
  End Property
End Class
<DefaultClassOptions> _
Public Class Object_A
  Inherits BaseObject
  Public Sub New(ByVal session As Session)
    MyBase.New(session)
  End Sub
  Private __name As String
  Public Property Name As String
    Get
      Return __name
    End Get
    Set
      SetPropertyValue("Name", __name, value)
    End Set
  End Property
  Public Property Object_B As Object_B
    Get
      Return Me.GetPropertyValue(Of Object_B)("Object_B")
    End Get
    Set
      Me.SetPropertyValue("Object_B", value)
    End Set
  End Property
  Public Property Object_C As Object_C
    Get
      Return Me.GetPropertyValue(Of Object_C)("Object_C")
    End Get
    Set
      Me.SetPropertyValue("Object_C", value)
    End Set
  End Property
End Class

  • Generate test data.
  • c#
  • VB

for (var i = 1; i <= 100; i++)
{
  var obj = ObjectSpace.CreateObject<Object_B>();
  obj.Name = i.ToString(CultureInfo.InvariantCulture) + "_Object_B";
}
for (var i = 1; i <= 100; i++)
{
  var obj = ObjectSpace.CreateObject<Object_C>();
  obj.Name = i.ToString(CultureInfo.InvariantCulture) + "_Object_C";
}
ObjectSpace.CommitChanges();
var specificationObject1List = ObjectSpace.GetObjects<Object_B>().OrderBy(a => a.Name).ToList();
var specificationObject2List = ObjectSpace.GetObjects<Object_C>().OrderBy(a => a.Name).ToList();
var applyFilterObject1 = ObjectSpace.CreateObject<Object_A>();
applyFilterObject1.Name = "1_ApplyFilterObject";
applyFilterObject1.Object_B = specificationObject1List[0];
applyFilterObject1.Object_C = specificationObject2List[0];
var applyFilterObject2 = ObjectSpace.CreateObject<Object_A>();
applyFilterObject2.Name = "2_ApplyFilterObject";
applyFilterObject2.Object_B = specificationObject1List[0];
applyFilterObject2.Object_C = specificationObject2List[24];
var applyFilterObject3 = ObjectSpace.CreateObject<Object_A>();
applyFilterObject3.Name = "3_ApplyFilterObject";
applyFilterObject3.Object_B = specificationObject1List[14];
applyFilterObject3.Object_C = specificationObject2List[29];
var applyFilterObject4 = ObjectSpace.CreateObject<Object_A>();
applyFilterObject4.Name = "4_ApplyFilterObject";
applyFilterObject4.Object_B = specificationObject1List[79];
applyFilterObject4.Object_C = specificationObject2List[59];
var applyFilterObject5 = ObjectSpace.CreateObject<Object_A>();
applyFilterObject5.Name = "5_ApplyFilterObject";
applyFilterObject5.Object_B = specificationObject1List[0];
applyFilterObject5.Object_C = specificationObject2List[29];
ObjectSpace.CommitChanges();

Dim i = 1
While i <= 100
  Dim obj = ObjectSpace.CreateObject(Of Object_B)()
  obj.Name = i.ToString(CultureInfo.InvariantCulture) + "_Object_B"
  i += 1
End While
Dim i = 1
While i <= 100
  Dim obj = ObjectSpace.CreateObject(Of Object_C)()
  obj.Name = i.ToString(CultureInfo.InvariantCulture) + "_Object_C"
  i += 1
End While
ObjectSpace.CommitChanges()
Private Dim specificationObject1List = ObjectSpace.GetObjects(Of Object_B)().OrderBy(Function(ByVal a) a.Name).ToList()
Private Dim specificationObject2List = ObjectSpace.GetObjects(Of Object_C)().OrderBy(Function(ByVal a) a.Name).ToList()
Private Dim applyFilterObject1 = ObjectSpace.CreateObject(Of Object_A)()
applyFilterObject1.Name = "1_ApplyFilterObject"
applyFilterObject1.Object_B = specificationObject1List(0)
applyFilterObject1.Object_C = specificationObject2List(0)
Private Dim applyFilterObject2 = ObjectSpace.CreateObject(Of Object_A)()
applyFilterObject2.Name = "2_ApplyFilterObject"
applyFilterObject2.Object_B = specificationObject1List(0)
applyFilterObject2.Object_C = specificationObject2List(24)
Private Dim applyFilterObject3 = ObjectSpace.CreateObject(Of Object_A)()
applyFilterObject3.Name = "3_ApplyFilterObject"
applyFilterObject3.Object_B = specificationObject1List(14)
applyFilterObject3.Object_C = specificationObject2List(29)
Private Dim applyFilterObject4 = ObjectSpace.CreateObject(Of Object_A)()
applyFilterObject4.Name = "4_ApplyFilterObject"
applyFilterObject4.Object_B = specificationObject1List(79)
applyFilterObject4.Object_C = specificationObject2List(59)
Private Dim applyFilterObject5 = ObjectSpace.CreateObject(Of Object_A)()
applyFilterObject5.Name = "5_ApplyFilterObject"
applyFilterObject5.Object_B = specificationObject1List(0)
applyFilterObject5.Object_C = specificationObject2List(29)
ObjectSpace.CommitChanges()

Note:

You will certainly be able to program the generation of any other test data volume.

  • Run the application. Make sure it is working.

multiply_select_3

  • Implement the FilterObject class. This class defines a filter object. It exposes ObjectSet<Object_B> and ObjectSet<Object_C> properties, which represent В’ and С’ subsets. These subsets will be edited by the end user in the application UI. The following code snippet demonstrates the code of FilterObject class.
  • c#
  • VB

public class FilterObject : XPCustomObject
{
  public FilterObject(Session session)
    : base(session)
  {
  }
  [Persistent("Oid")]
  [Key(true)]
  [Browsable(false)]
  [MemberDesignTimeVisibility(false)]
  private Guid oid = Guid.Empty;
  [Browsable(false)]
  [PersistentAlias("oid")]
  public Guid Oid
  {
    get
    {
      return this.oid;
    }
    set
    {
      this.oid = value;
    }
  }
  private string _name;
  public string Name
  {
    get
    {
      return _name;
    }
    set
    {
      SetPropertyValue("Name", ref _name, value);
    }
  }
  [NonPersistent]
  public ObjectSet<Object_B> FilterObject_B;
  [NonPersistent]
  [LocalContext("Context1")]
  public ObjectSet<Object_C> FilterObject_C;
  protected override void OnSaving()
  {
    base.OnSaving();
    ObjectSetPersistentOwnerHelper.UpdateOwnwerId(this);
  }
  public override void AfterConstruction()
  {
    ObjectSetPersistentOwnerHelper.CreateObjectSets(this, ObjectSetPersistentOwnerHelper.OwnerIdUndefined);
    base.AfterConstruction();
  }
  protected override void OnLoaded()
  {
    ObjectSetPersistentOwnerHelper.CreateObjectSets(this, this.Session.Xafari().GetKeyValueAsString(this));
  }
}

Public Class FilterObject
  Inherits XPCustomObject
  Public Sub New(ByVal session As Session)
    MyBase.New(session)
  End Sub
  <Persistent("Oid")> _
<Key(True)> _
<Browsable(False)> _
<MemberDesignTimeVisibility(False)> _
Private _oid As Guid = Guid.Empty
  <Browsable(False)> _
<PersistentAlias("oid")> _
Public Property Oid As Guid
    Get
      Return Me._oid
    End Get
    Set
      Me._oid = value
    End Set
  End Property
  Private __name As String
  Public Property Name As String
    Get
      Return __name
    End Get
    Set
      SetPropertyValue("Name", __name, value)
    End Set
  End Property
  <NonPersistent> _
Public FilterObject_B As ObjectSet(Of Object_B)
  <NonPersistent> _
<LocalContext("Context1")> _
Public FilterObject_C As ObjectSet(Of Object_C)
  Protected Overrides Sub OnSaving()
    MyBase.OnSaving()
    ObjectSetPersistentOwnerHelper.UpdateOwnwerId(Me)
  End Sub
  Public Overrides Sub AfterConstruction()
    ObjectSetPersistentOwnerHelper.CreateObjectSets(Me, ObjectSetPersistentOwnerHelper.OwnerIdUndefined)
    MyBase.AfterConstruction()
  End Sub
  Protected Overrides Sub OnLoaded()
    ObjectSetPersistentOwnerHelper.CreateObjectSets(Me, Me.Session.Xafari().GetKeyValueAsString(Me))
  End Sub
End Class

Notes:

FilterObject is persistent in this example, but persistence is not necessary. If you declare a non-persistent class of a filter object, you'll need to perform some additional steps, for example, when the object is initialized. After reading all the documentation you will get a better idea.

FilterObject is inherited from the XPCustomObject. This allows the developer to set the Oid field in the code himself. However, the developer cannot do the same with BaseObject descendants. The need to set Oid manually will become clear a bit later.

FilterObject_B and FilterObject_С properties provide access to  В’ and С’ sets (Selections). These properties are always non-persistent as the sets are stored in the XPObjectSet object.

Learn More topic provides detailed information about used types.

  • Create an object of class FilterObject, this code must work after the test data generation.
  • c#
  • VB

public void smth()
{
  var filterObject = ObjectSpace.CreateObject<FilterObject>();
  filterObject.Name = "FilterObject";
  filterObject.Oid = new Guid("89BAFC65-28E6-480E-9424-07157D554093");
  filterObject.FilterObject_B.Criteria = CriteriaOperator.Parse("StartsWith([Name], '1')");
  filterObject.FilterObject_B.SelectionType = MultipleSelectionType.Criteria;
  filterObject.FilterObject_C.SetSelectedObject(new List<Object_C>() { specificationObject2List[0], specificationObject2List[10], specificationObject2List[55] });
  filterObject.FilterObject_C.SelectionType = MultipleSelectionType.Multiple;
  ObjectSpace.CommitChanges();
}

Public Sub smth()
  Dim filterObject = ObjectSpace.CreateObject(Of FilterObject)()
  filterObject.Name = "FilterObject"
  filterObject.Oid = New Guid("89BAFC65-28E6-480E-9424-07157D554093")
  filterObject.FilterObject_B.Criteria = CriteriaOperator.Parse("StartsWith([Name], '1')")
  filterObject.FilterObject_B.SelectionType = MultipleSelectionType.Criteria
  filterObject.FilterObject_C.SetSelectedObject(New List(Of Object_C)() With {specificationObject2List(0), specificationObject2List(10), specificationObject2List(55)})
  filterObject.FilterObject_C.SelectionType = MultipleSelectionType.Multiple
  ObjectSpace.CommitChanges()
End Sub

  •  Add FilterObjectOpenController View Controller and implement showFilterObject Action. Its task is to open filterObject Detail View.
  • c#
  • VB

public partial class FilterObjectOpenController : ViewController<ListView>
{
  public FilterObjectOpenController()
  {
    InitializeComponent();
    var showFilterObject = new DevExpress.ExpressApp.Actions.SimpleAction(this.components) { Caption = "ShowFilterObject", Id = "showFilterObject" };
    showFilterObject.Execute += new DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(showFilterObject_Execute);
    RegisterActions(components);
    this.TargetObjectType = typeof(Object_A);
  }
  void showFilterObject_Execute(object sender, DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs e)
  {
    var objectSpace = this.Application.CreateObjectSpace();
    var filterObject = objectSpace.GetObjects<FilterObject>()[0];
    e.ShowViewParameters.CreatedView = this.Application.CreateDetailView(objectSpace, filterObject, true);
    e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow;
  }
}

Public Partial Class FilterObjectOpenController
  Inherits ViewController(Of ListView)
  Public Sub New()
    InitializeComponent()
    Dim showFilterObject = New DevExpress.ExpressApp.Actions.SimpleAction(Me.components) With {.Caption = "ShowFilterObject", .Id = "showFilterObject"}
    showFilterObject.Execute += New DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(showFilterObject_Execute)
    RegisterActions(components)
    Me.TargetObjectType = GetType(Object_A)
  End Sub
  Private Sub showFilterObject_Execute(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
    Dim objectSpace = Me.Application.CreateObjectSpace()
    Dim filterObject = objectSpace.GetObjects(Of FilterObject)()(0)
    e.ShowViewParameters.CreatedView = Me.Application.CreateDetailView(objectSpace, filterObject, True)
    e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow
  End Sub
End Class

Note:

The above code takes the first object of FilterObject type. In this example, it is a created filterObject.

  • Run the application. The Multiple Selection Editor allows you to set lists of elements in В’ and С’ sets. The editor is described in the End-User Capabilities topic.

multiply_select_4

  • Modify the FilterObjectOpenController code by adding another 2 Actions: applyFilterObject_B and applyFilterObject_C. The code snippet below demonstrates the final version of the FilterObjectOpenController class.
  • c#
  • VB

public partial class FilterObjectOpenController : ViewController<ListView>
{
  public FilterObjectOpenController()
  {
    InitializeComponent();
    var showFilterObject = new DevExpress.ExpressApp.Actions.SimpleAction(this.components) { Caption = "ShowFilterObject", Id = "showFilterObject" };
    showFilterObject.Execute += new DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(showFilterObject_Execute);
    var applyFilterObject_B = new DevExpress.ExpressApp.Actions.SimpleAction(this.components) { Caption = "ApplyFilterObject_B", Id = "applyFilterObject_B" };
    applyFilterObject_B.Execute += new DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(applyFilterObject_B_Execute);
    var applyFilterObject_C = new DevExpress.ExpressApp.Actions.SimpleAction(this.components) { Caption = "ApplyFilterObject_C", Id = "applyFilterObject_C" };
    applyFilterObject_C.Execute += new DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(applyFilterObject_C_Execute);
    RegisterActions(components);
    this.TargetObjectType = typeof(Object_A);
  }
  void applyFilterObject_B_Execute(object sender, DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs e)
  {
    var filterObject = this.ObjectSpace.GetObjects<FilterObject>()[0];
    if (this.View.CollectionSource.Criteria.ContainsKey("applyFilterObject_B"))
      this.View.CollectionSource.Criteria["applyFilterObject_B"] = filterObject.FilterObject_B.GetCriteria("Object_B");
    else
      this.View.CollectionSource.Criteria.Add("applyFilterObject_B", filterObject.FilterObject_B.GetCriteria("Object_B"));
  }
  void applyFilterObject_C_Execute(object sender, DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs e)
  {
    var filterObject = this.ObjectSpace.GetObjects<FilterObject>()[0];
    if (this.View.CollectionSource.Criteria.ContainsKey("applyFilterObject_C"))
      this.View.CollectionSource.Criteria["applyFilterObject_C"] = filterObject.FilterObject_C.GetCriteria("Object_C");
    else
      this.View.CollectionSource.Criteria.Add("applyFilterObject_C", filterObject.FilterObject_C.GetCriteria("Object_C"));
  }
  void showFilterObject_Execute(object sender, DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs e)
  {
    var objectSpace = this.Application.CreateObjectSpace();
    var filterObject = objectSpace.GetObjects<FilterObject>()[0];
    e.ShowViewParameters.CreatedView = this.Application.CreateDetailView(objectSpace, filterObject, true);
    e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow;
  }
}

Public Partial Class FilterObjectOpenController
  Inherits ViewController(Of ListView)
  Public Sub New()
    InitializeComponent()
    Dim showFilterObject = New DevExpress.ExpressApp.Actions.SimpleAction(Me.components) With {.Caption = "ShowFilterObject", .Id = "showFilterObject"}
    showFilterObject.Execute += New DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(showFilterObject_Execute)
    Dim applyFilterObject_B = New DevExpress.ExpressApp.Actions.SimpleAction(Me.components) With {.Caption = "ApplyFilterObject_B", .Id = "applyFilterObject_B"}
    applyFilterObject_B.Execute += New DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(applyFilterObject_B_Execute)
    Dim applyFilterObject_C = New DevExpress.ExpressApp.Actions.SimpleAction(Me.components) With {.Caption = "ApplyFilterObject_C", .Id = "applyFilterObject_C"}
    applyFilterObject_C.Execute += New DevExpress.ExpressApp.Actions.SimpleActionExecuteEventHandler(applyFilterObject_C_Execute)
    RegisterActions(components)
    Me.TargetObjectType = GetType(Object_A)
  End Sub
  Private Sub applyFilterObject_B_Execute(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
    Dim filterObject = Me.ObjectSpace.GetObjects(Of FilterObject)()(0)
    If Me.View.CollectionSource.Criteria.ContainsKey("applyFilterObject_B") Then
      Me.View.CollectionSource.Criteria("applyFilterObject_B") = filterObject.FilterObject_B.GetCriteria("Object_B")
    Else
      Me.View.CollectionSource.Criteria.Add("applyFilterObject_B", filterObject.FilterObject_B.GetCriteria("Object_B"))
    End If
  End Sub
  Private Sub applyFilterObject_C_Execute(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
    Dim filterObject = Me.ObjectSpace.GetObjects(Of FilterObject)()(0)
    If Me.View.CollectionSource.Criteria.ContainsKey("applyFilterObject_C") Then
      Me.View.CollectionSource.Criteria("applyFilterObject_C") = filterObject.FilterObject_C.GetCriteria("Object_C")
    Else
      Me.View.CollectionSource.Criteria.Add("applyFilterObject_C", filterObject.FilterObject_C.GetCriteria("Object_C"))
    End If
  End Sub
  Private Sub showFilterObject_Execute(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
    Dim objectSpace = Me.Application.CreateObjectSpace()
    Dim filterObject = objectSpace.GetObjects(Of FilterObject)()(0)
    e.ShowViewParameters.CreatedView = Me.Application.CreateDetailView(objectSpace, filterObject, True)
    e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow
  End Sub
End Class

ApplyFilterObject_B Action  filters Object_A objects, it will leave only those objects which have a reference to an Object_B object which is included in B’ set.

ApplyFilterObject_C Action also filters Object_A objects, it will leave only those objects which have a reference to an Object_С object which is included in С’ set.

Learn More topic provides detailed information about used methods.

  • Run the application. Execute alternately ApplyFilterObject_B Action and ApplyFilterObject_C Action, only one object will be filtered.

multiply_select_5

You can load and examine ObjectSetSample solution.