Example E1744
Visible to All Users

How to search for XAF objects using a complex criterion

This example creates a pop-up window that allows users to perform a custom object search.

MySearchClass window

Implementation Details

  1. Create a non-persistent class with properties used to search persistent objects.
    File to review: MySearchClass.cs
    C#
    [DomainComponent] public class MySearchClass : NonPersistentBaseObject { [XafDisplayName("FirstName contains:")] public string FirstName { get; set; } [XafDisplayName("Age is equal to:")] public int Age { get; set; } // ... }
  2. Add a collection of persistent objects that contains the search results.
    File to review: MySearchClass.cs
    C#
    [DomainComponent] public class MySearchClass : NonPersistentBaseObject { // ... private IList<Contact> _contacts = new List<Contact>(); [XafDisplayName("Results:")] public IList<Contact> Contacts { get { return _contacts; } } }
  3. Add the MySearch action that populates the collection.
    File to review: MySearchController.cs
    C#
    public class MySearchController : ObjectViewController<DetailView, MySearchClass> { public MySearchController() { var myAction1 = new SimpleAction(this, "MySearch", "MySearchCategory"); myAction1.Execute += MyAction1_Execute; } // ... }
  4. When a user clicks the MySearch action, create a criterion based on the properties described in the first step and get persistent objects that fit this criterion.
    File to review: MySearchController.cs
    C#
    public class MySearchController : ObjectViewController<DetailView, MySearchClass> { // ... private void MyAction1_Execute(object sender, SimpleActionExecuteEventArgs e) { var mySearchObject = (MySearchClass)View.CurrentObject; var persistentOS = Application.CreateObjectSpace(typeof(Contact)); var criterion = CriteriaOperator.FromLambda<Contact>(x => x.FirstName.Contains(mySearchObject.FirstName) || x.Age == mySearchObject.Age); var results = persistentOS.GetObjects<Contact>(criterion); mySearchObject.SetContacts(results); } }
  5. Create the MyShowSearchAction to display the MySearchClass detail view from the Contact list view in a pop-up window.
    File to review: MyShowSearchController.cs
    C#
    public class MyShowSearchController : ObjectViewController<ListView, Contact> { public MyShowSearchController() { var mypopAction1 = new PopupWindowShowAction(this, "MyShowSearchAction", PredefinedCategory.Edit); mypopAction1.TargetViewNesting = Nesting.Root; mypopAction1.CustomizePopupWindowParams += MyAction1_CustomizePopupWindowParams; } private void MyAction1_CustomizePopupWindowParams(object sender, CustomizePopupWindowParamsEventArgs e) { var nonPersistentOS = (NonPersistentObjectSpace)Application.CreateObjectSpace(typeof(MySearchClass)); var persistentOS = Application.CreateObjectSpace(typeof(Contact)); nonPersistentOS.AdditionalObjectSpaces.Add(persistentOS); var obj = nonPersistentOS.CreateObject<MySearchClass>(); nonPersistentOS.CommitChanges(); var view = Application.CreateDetailView(nonPersistentOS, obj); e.View = view; } }

Files to Review

Documentation

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

EFCore/ComplexSearchEF/ComplexSearchEF.Module/BusinessObjects/MySearchClass.cs
C#
using DevExpress.ExpressApp; using DevExpress.ExpressApp.DC; using DevExpress.Persistent.BaseImpl; using MySolution.Module.BusinessObjects; namespace dxTestSolution.Module.BusinessObjects { [DomainComponent] public class MySearchClass : NonPersistentBaseObject { [XafDisplayName("FirstName contains:")] public string FirstName { get; set; } [XafDisplayName("Age is equal to:")] public int Age { get; set; } public void SetContacts(IList<Contact> res) { _contacts = res; OnPropertyChanged(nameof(Contacts)); } private IList<Contact> _contacts = new List<Contact>(); [XafDisplayName("Results:")] public IList<Contact> Contacts { get { return _contacts; } } } }
EFCore/ComplexSearchEF/ComplexSearchEF.Module/Controllers/MySearchController.cs
C#
using DevExpress.Data.Filtering; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Actions; using dxTestSolution.Module.BusinessObjects; using MySolution.Module.BusinessObjects; namespace dxTestSolution.Module.Controllers { public class MySearchController : ObjectViewController<DetailView, MySearchClass> { public MySearchController() { var myAction1 = new SimpleAction(this, "MySearch", "MySearchCategory"); myAction1.Execute += MyAction1_Execute; } private void MyAction1_Execute(object sender, SimpleActionExecuteEventArgs e) { var mySearchObject = (MySearchClass)View.CurrentObject; var persistentOS = Application.CreateObjectSpace(typeof(Contact)); var criterion = CriteriaOperator.FromLambda<Contact>(x => x.FirstName.Contains(mySearchObject.FirstName) || x.Age == mySearchObject.Age); var results = persistentOS.GetObjects<Contact>(criterion); mySearchObject.SetContacts(results); } } }
EFCore/ComplexSearchEF/ComplexSearchEF.Module/Controllers/MyShowSearchController.cs
C#
using DevExpress.ExpressApp; using DevExpress.ExpressApp.Actions; using DevExpress.Persistent.Base; using dxTestSolution.Module.BusinessObjects; using MySolution.Module.BusinessObjects; namespace dxTestSolution.Module.Controllers { public class MyShowSearchController : ObjectViewController<ListView, Contact> { public MyShowSearchController() { var mypopAction1 = new PopupWindowShowAction(this, "MyShowSearchAction", PredefinedCategory.Edit); mypopAction1.TargetViewNesting = Nesting.Root; mypopAction1.CustomizePopupWindowParams += MyAction1_CustomizePopupWindowParams; } private void MyAction1_CustomizePopupWindowParams(object sender, CustomizePopupWindowParamsEventArgs e) { var nonPersistentOS = (NonPersistentObjectSpace)Application.CreateObjectSpace(typeof(MySearchClass)); var persistentOS = Application.CreateObjectSpace(typeof(Contact)); nonPersistentOS.AdditionalObjectSpaces.Add(persistentOS); var obj = nonPersistentOS.CreateObject<MySearchClass>(); nonPersistentOS.CommitChanges(); var view = Application.CreateDetailView(nonPersistentOS, obj); e.View = view; } } }
EFCore/ComplexSearchEF/ComplexSearchEF.Module/Model.DesignedDiffs.xafml
Code
<?xml version="1.0" encoding="utf-8"?> <Application Title="ComplexSearchEF"> <SchemaModules> <SchemaModule Name="SystemModule" Version="22.2.6.0" IsNewNode="True" /> </SchemaModules> <Views> <DetailView Id="MySearchClass_DetailView"> <Items> <PropertyEditor Id="Age" Caption="Age is equal to" /> <PropertyEditor Id="Contacts" Caption="Results" /> <PropertyEditor Id="FirstName" Caption="FirstName contains" /> <ActionContainerViewItem Id="MySearchCategory" ActionContainer="MySearchCategory" Caption="MySearchCategory(8)" IsNewNode="True" /> <StaticText Id="ORItem" Text="OR" Caption="ORItem(10)" IsNewNode="True" /> </Items> <Layout> <LayoutGroup Id="Main" RelativeSize="100"> <LayoutGroup Id="SimpleEditors" RelativeSize="10.725806451612904"> <LayoutGroup Id="MySearchClass" RelativeSize="100"> <LayoutItem Id="FirstName" RelativeSize="28.571428571428573" /> <LayoutItem Id="ORItem" ViewItem="ORItem" Index="1" RelativeSize="17.293233082706767" IsNewNode="True" /> <LayoutItem Id="Age" Index="2" RelativeSize="22.55639097744361" /> <LayoutItem Id="MySearchCategory" ViewItem="MySearchCategory" Index="3" RelativeSize="31.57894736842105" IsNewNode="True" /> </LayoutGroup> </LayoutGroup> <LayoutGroup Id="Contacts_Group" Direction="Vertical" RelativeSize="89.2741935483871" Caption="Results:"> <LayoutItem Id="Contacts" RelativeSize="100" /> </LayoutGroup> </LayoutGroup> </Layout> </DetailView> </Views> </Application>

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.