获取所有后代类型的基类

时间:2023-01-14 14:33:17

I have a base class called BaseEvent and several descendants classes:

我有一个名为BaseEvent的基类和几个后代类:

public class BaseEvent {
    // the some properties
    // ...
}

[MapInheritance(MapInheritanceType.ParentTable)]
public class Film : BaseEvent {
   // the some properties
   // ...
}
[MapInheritance(MapInheritanceType.ParentTable)]
public class Concert : BaseEvent {
    // the some properties
    // ...
}

I have a code which create the BaseEvent instance at runtime:

我有一个代码在运行时创建BaseEvent实例:

BaseEvent event = new BaseEvent();
// assign values for a properties
// ...    
baseEvent.XPObjectType = Database.XPObjectTypes.SingleOrDefault(
    t => t.TypeName == "MyApp.Module.BO.Events.BaseEvent");

Now, this event will be shows in BaseEvent list view.

现在,此事件将显示在BaseEvent列表视图中。

I want to do the following: when a user click Edit button then show in list view lookup field with all descendants types. And when user saves record change ObjectType to selected value.

我想要执行以下操作:当用户单击“编辑”按钮,然后在列表视图查找字段中显示所有后代类型。当用户保存记录时,将ObjectType更改为选定值。

How can I do this?
Thanks.

我怎样才能做到这一点?谢谢。

PS. this is asp.net app.

PS。这是asp.net应用程序。

1 个解决方案

#1


5  

I'm not sure that your approach is correct for what you are trying to achieve. First, I'll answer the question you have asked, and afterwards I'll try to explain how the XAF already provides the functionality you are trying to achieve, namely how to choose which subclass of record to create from the user interface.

我不确定你的方法对于你想要实现的目标是否正确。首先,我将回答你提出的问题,然后我将尝试解释XAF如何提供你想要实现的功能,即如何从用户界面中选择要创建的记录的子类。

In order to create a property which allows the user to choose a Type within the application, you can declare a TypeConverter:

为了创建允许用户在应用程序中选择Type的属性,可以声明TypeConverter:

public class EventClassInfoTypeConverter : LocalizedClassInfoTypeConverter
{
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        List<Type> values = new List<Type>();
        foreach (ITypeInfo info in XafTypesInfo.Instance.PersistentTypes)
        {
            if ((info.IsVisible && info.IsPersistent) && (info.Type != null))
            {
                // select BaseEvent subclasses
                if (info.Type.IsSubclassOf(typeof(BaseEvent))) 
                    values.Add(info.Type);
            }
        }
        values.Sort(this);
        values.Insert(0, null);
        return new TypeConverter.StandardValuesCollection(values);
    }
}

And then your base event class would look like:

然后你的基本事件类看起来像:

public class BaseEvent: XPObject
{
    public BaseEvent(Session session)
        : base(session)
    { }

    private Type _EventType;
    [TypeConverter(typeof(EventClassInfoTypeConverter))]
    public Type EventType
    {
        get
        {
            return _EventType;
        }
        set
        {
            SetPropertyValue("EventType", ref _EventType, value);
        }
    }
}

However, I suspect this is not the functionality you require. Modifying the value of the property will NOT change the base type of the record. That is, you will end up with a record of type BaseEvent which has a property Type equal to 'Concert' or 'Film'.

但是,我怀疑这不是您需要的功能。修改属性的值不会更改记录的基本类型。也就是说,您最终会得到BaseEvent类型的记录,其类型等于'Concert'或'Film'。

XAF already provides a mechanism for selecting the type of record to create. In your scenario, you will find that the New button is a dropdown with your different subclasses as options:

XAF已经提供了一种机制来选择要创建的记录类型。在您的场景中,您会发现“新建”按钮是一个下拉列表,其中包含不同的子类作为选项:

获取所有后代类型的基类

Therefore you do not need to create a 'type' property within your object. If you need a column to show the type of event in the list view, you can declare a property as follows

因此,您无需在对象中创建“类型”属性。如果需要列在列表视图中显示事件类型,则可以按如下方式声明属性

[PersistentAlias("XPObjectType.Name")]
public string EventType
{
    get
    {
        return base.ClassInfo.ClassType.Name;
    }
}

#1


5  

I'm not sure that your approach is correct for what you are trying to achieve. First, I'll answer the question you have asked, and afterwards I'll try to explain how the XAF already provides the functionality you are trying to achieve, namely how to choose which subclass of record to create from the user interface.

我不确定你的方法对于你想要实现的目标是否正确。首先,我将回答你提出的问题,然后我将尝试解释XAF如何提供你想要实现的功能,即如何从用户界面中选择要创建的记录的子类。

In order to create a property which allows the user to choose a Type within the application, you can declare a TypeConverter:

为了创建允许用户在应用程序中选择Type的属性,可以声明TypeConverter:

public class EventClassInfoTypeConverter : LocalizedClassInfoTypeConverter
{
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        List<Type> values = new List<Type>();
        foreach (ITypeInfo info in XafTypesInfo.Instance.PersistentTypes)
        {
            if ((info.IsVisible && info.IsPersistent) && (info.Type != null))
            {
                // select BaseEvent subclasses
                if (info.Type.IsSubclassOf(typeof(BaseEvent))) 
                    values.Add(info.Type);
            }
        }
        values.Sort(this);
        values.Insert(0, null);
        return new TypeConverter.StandardValuesCollection(values);
    }
}

And then your base event class would look like:

然后你的基本事件类看起来像:

public class BaseEvent: XPObject
{
    public BaseEvent(Session session)
        : base(session)
    { }

    private Type _EventType;
    [TypeConverter(typeof(EventClassInfoTypeConverter))]
    public Type EventType
    {
        get
        {
            return _EventType;
        }
        set
        {
            SetPropertyValue("EventType", ref _EventType, value);
        }
    }
}

However, I suspect this is not the functionality you require. Modifying the value of the property will NOT change the base type of the record. That is, you will end up with a record of type BaseEvent which has a property Type equal to 'Concert' or 'Film'.

但是,我怀疑这不是您需要的功能。修改属性的值不会更改记录的基本类型。也就是说,您最终会得到BaseEvent类型的记录,其类型等于'Concert'或'Film'。

XAF already provides a mechanism for selecting the type of record to create. In your scenario, you will find that the New button is a dropdown with your different subclasses as options:

XAF已经提供了一种机制来选择要创建的记录类型。在您的场景中,您会发现“新建”按钮是一个下拉列表,其中包含不同的子类作为选项:

获取所有后代类型的基类

Therefore you do not need to create a 'type' property within your object. If you need a column to show the type of event in the list view, you can declare a property as follows

因此,您无需在对象中创建“类型”属性。如果需要列在列表视图中显示事件类型,则可以按如下方式声明属性

[PersistentAlias("XPObjectType.Name")]
public string EventType
{
    get
    {
        return base.ClassInfo.ClassType.Name;
    }
}