Фильтрация источника данных свойства класса 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), когда вам нужно обновить постоянное свойство через непостоянное. Я надеюсь, что мое решение теперь яснее.