В разделе Множественный выбор была сформулирована простая абстрактная задача. Здесь будет продемонстрировано ее решение с использованием класса ObjectSet<T>. Создайте пробное Win – приложение для демонстрации. Назовите его ObjectSetSample.

Выполните следующие шаги.

 

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

        }

    }

 

 

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();

 

Замечание: разумеется, вы можете запрограммировать генерацию любого другого объема тестовых данных.

 

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.OwnertIdUndefined);

            base.AfterConstruction();

        }

        protected override void OnLoaded(){

            ObjectSetPersistentOwnerHelper.CreateObjectSets(this, this.Session.GetKeyValueAsString(this));

        }

    }

 

Замечания:

FilterObject в данном примере персистентный, но персистентность не обязательна. Если вы определите неперсистентный класс объекта фильтрации, то придётся выполнять ряд дополнительных действий, например при инициализации объекта. По прочтении всей документации вы получите более полное представление.

FilterObject является наследником XPCustomObject. Это позволит разработчику  установить ключевое поле (Oid) в коде самостоятельно. Наследники BaseObject не обладают такой возможностью. Необходимость задавать Oid вручную станет ясна далее.

Свойства FilterObject_B и FilterObject_С предоставляют доступ к множествам В’ и С’ (Выборкам). Эти свойства всегда неперсистентны, так как множества хранятся в объекте XPObjectSet.  

Детальное описание используемых типов приведено в документе Руководство разработчика.

 

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 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;

        }

    }

 

Замечание:

Вышеприведенный код берет первый объект типа FilterObject. В данном примере это будет уже созданный filterObject.

 

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);

 

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"));

}

 

Action ApplyFilterObject_B фильтрует объекты Object_A, он оставит только те, у которых есть ссылка на объект Object_B, который входит в множество B’.

Action ApplyFilterObject_C тоже фильтрует объекты Object_A, он оставит только те, у которых есть ссылка на объект Object_С, который входит в множество С’.

Детальное описание используемых методов приведено в документе Руководство разработчика.

Итог:  получен небольшой и не сложный пример использования функционала Множественного Выбора. Изучите остальные документы этого раздела, чтобы получить полное представление.