Фильтрация источника данных свойства класса Devexpress XAF

Я объявил класс как-то так

[DefaultClassOptions]
public class Test:XPObject
{
    Type _classType;

    [NonPersistent]
    public Type ClassType
    {
         get { return _classType; }
         set { SetPropertyValue("ClassType", ref _classType, value); }
    }
}

проблема в том, что это поле отображается в виде выпадающего списка, но у меня нет контроля над этим списком, я не могу отфильтровать или настроить этот список. он всегда открывается со всеми доступными типами во всех сборках. не работали ни атрибуты DataSourceProperty, ни DataSourceCriteria.

я могу сделать это с другими постоянными классами, но я не могу сделать с типизированными полями типа.

если есть обходной путь, пожалуйста, помогите. заранее спасибо.

2 ответа

Решение

Реализуйте потомок LocalizedClassInfoTypeConverter, как:

public class LocalizedClassInfoTypeConverter<T> : LocalizedClassInfoTypeConverter {
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
            List<Type> list = new List<Type>();
            foreach (Type t in base.GetStandardValues(context)) {
                if (typeof(T).IsAssignableFrom(t)) list.Add(t);
            }
            return new StandardValuesCollection(list);
        }
    }

Затем используйте его следующим образом:

[DefaultClassOptions]
public class Test:XPObject
{
    Type _classType;
    [ValueConverter(typeof(TypeToStringConverter))]
    [TypeConverter(typeof(LocalizedClassInfoTypeConverter<MyBaseTypeOrInterface>))]
    public Type ClassType
    {
         get { return _classType; }
         set { SetPropertyValue("ClassType", ref _classType, value); }
    }

}

Источник: https://www.devexpress.com/Support/Center/Question/Details/Q364986

Согласно документации XAF атрибуты DataSourceXXX должны работать только для типов бизнес-объектов по умолчанию, поэтому System.Type здесь не может использоваться. Тем не менее, в качестве альтернативного решения вы можете создать непостоянную оболочку POCO и использовать DataSourcePropertyAttribute для предоставления отфильтрованного источника данных поиска. Найдите пример кода для аналогичной задачи в разделе Очень интересный способ обновить и отобразить постоянное свойство через непостоянное свойство.

РЕДАКТИРОВАТЬ: Вот также пример кода для вашего конкретного случая:

using System;
using System.Collections.Generic;
using System.Linq;
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Xpo;

namespace SimpleProjectManager.Module.BusinessObjects {
    [DomainComponent]
    public class NonPersistentTypeWrapper {
        public string FullName { get; set; }
    }
    [DefaultClassOptions]
    public class PersistentTestObject : BaseObject {
        public PersistentTestObject(Session session) : base(session) { }
        [Persistent("StringColumnNameInDb")]
        private string stringFieldThoseValueIsStoredInDb;

        private NonPersistentTypeWrapper _TypeProperty;
        [NonPersistent, DataSourceProperty("TypesDataSource")]
        public NonPersistentTypeWrapper TypeProperty {
            get {
                if(_TypeProperty == null && !string.IsNullOrEmpty(stringFieldThoseValueIsStoredInDb)) {
                    _TypeProperty = TypesDataSource.Single(v => v.FullName == stringFieldThoseValueIsStoredInDb);
                }
                return _TypeProperty;
            }
            set {
                SetPropertyValue<NonPersistentTypeWrapper>("TypeProperty", ref _TypeProperty, value);
                if(!IsLoading && !IsSaving) {
                    stringFieldThoseValueIsStoredInDb = value != null ? value.FullName : string.Empty;
                    OnChanged("stringFieldThoseValueIsStoredInDb");
                }
            }
        }
        private List<NonPersistentTypeWrapper> _TypesDataSource = null;
        protected IList<NonPersistentTypeWrapper> TypesDataSource {
            get {
                if(_TypesDataSource == null) {
                    _TypesDataSource = new List<NonPersistentTypeWrapper>();
                    foreach(Type type in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()) {
                        if(type.FullName.Contains("Planning")) {// some basic filtering...
                            _TypesDataSource.Add(new NonPersistentTypeWrapper() { FullName = type.FullName });
                        }
                    }
                }
                return _TypesDataSource;
            }
        }
    }
}

и результат: введите описание изображения здесьХотя это выглядит немного сложнее, этот подход универсален и может использоваться для любого типа свойства (не только для System.Type), когда вам нужно обновить постоянное свойство через непостоянное. Я надеюсь, что мое решение теперь яснее.

Другие вопросы по тегам