Devexpress XAF类属性数据源过滤

时间:2014-07-18 11:31:11

标签: devexpress xaf xpo

我宣布了类似这样的课程

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

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

问题是,此字段显示为下拉列表,但我无法控制此列表,我无法过滤或自定义此列表。它始终以所有程序集中的所有可访问类型打开。 DataSourceProperty和DataSourceCriteria属性都不起作用。

我可以使用其他持久类来完成此操作,但我无法使用" Type"键入的字段。

如果有解决方法请帮忙。提前谢谢。

2 个答案:

答案 0 :(得分:3)

实现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

答案 1 :(得分:2)

根据XAF文档,默认情况下,DataSourceXXX属性仅适用于业务对象类型,因此不能在此处使用System.Type。 也就是说,作为替代解决方案,您可以创建非持久性包装器POCO并使用DataSourcePropertyAttribute来提供过滤的查找数据源。在A very interesting way to update and display a persistent property via a non-persistent one

找到类似任务的示例代码

修改 以下是您的特定情况的一些示例代码:

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

结果:enter image description here 虽然这看起来有点复杂,但这种方法是通用的,当您需要通过非持久属性更新持久属性时,可以用于任何属性类型(不仅仅用于System.Type)。我希望我的解决方案现在更加清晰。