Skip to content

对象列表属性

如果一个属性的类型是List类型,List的每一项又包含了子属性,那么可以通过标注ObjectListPropertyAttribute,使得活字格设计器可以通过弹出二级对话框来编辑该属性。

注意,

  1. ItemType属性里声明的类型必须与项目属性类型一致
  2. 自定义对象必须实现 INamedObject 接口
  3. 属性的返回值必须是 List<INamedObject>
  4. 自定义对象的类型应该从 ObjectPropertyBase 类派生,以确保在单元格复制的时候,子属性可以被正确的深克隆(ObjectPropertyBase实现了默认的深克隆逻辑)

基本用法

csharp
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyPlugin
{
    public class MyPluginServerCommand : Command, ICommandExecutableInServerSideAsync
    {
        [ObjectListProperty(ItemType = typeof(MyObj))]
        public List<INamedObject> MyProperty { get; set; } = new List<INamedObject>();

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            return new ExecuteResult();
        }
        
        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }
    }
    
    public class MyObj : ObjectPropertyBase, INamedObject
    {
        public string Name { get; set; }
        public string SubProperty1 { get; set; }
        public string SubProperty2 { get; set; }
        public string SubProperty3 { get; set; }
        public string SubProperty4 { get; set; }
    }
}

在设计器中效果如下:

对象列表属性编辑器

自定义子属性

列表项目的子属性也可以通过标注来控制属性编辑控件。下面例子中,额外声明了两个属性分别使用FormulaProperty公式编辑器和ComboProperty组合框编辑器。具体标注的用法请参考之前的章节:

csharp
public class MyPluginServerCommand : Command, ICommandExecutableInServerSideAsync
{
    [ObjectListProperty(ItemType = typeof(MyObj))]
    public List<INamedObject> MyProperty { get; set; } = new List<INamedObject>();

    public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
    {
        return new ExecuteResult();
    }
    
    public override CommandScope GetCommandScope()
    {
        return CommandScope.ExecutableInServer;
    }
}

public class MyObj : ObjectPropertyBase, INamedObject
{
    public string Name { get; set; }
    public string Description { get; set; }

    [FormulaProperty]
    public object FormulaProperty { get; set; }

    [ComboProperty(ValueList = "选项1|选项2|选项3")]
    public string Type { get; set; }
}

在设计器中效果如下:

子属性添加标注效果

高级设置

如果需要更细致的控制,可以通过ObjectListPropertyAttribute的其他属性来控制:

1. 控制列表最大元素个数

设置ObjectListPropertyAttributeMaxCount属性:

csharp
public class MyPluginServerCommand : Command, ICommandExecutableInServerSideAsync
{
    [ObjectListProperty(ItemType = typeof(MyObj), MaxCount = 4)]
    public List<INamedObject> MyProperty { get; set; } = new List<INamedObject>();

    public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
    {
        return new ExecuteResult();
    }
    
    public override CommandScope GetCommandScope()
    {
        return CommandScope.ExecutableInServer;
    }
}

public class MyObj : ObjectPropertyBase, INamedObject
{
    public string Name { get; set; }
    public string SubProperty1 { get; set; }
    public string SubProperty2 { get; set; }
    public string SubProperty3 { get; set; }
    public string SubProperty4 { get; set; }
}

2. 控制默认结点名称

设置ObjectListPropertyAttributeDefaultName属性:

csharp
public class MyPluginServerCommand : Command, ICommandExecutableInServerSideAsync
{
    [ObjectListProperty(ItemType = typeof(MyObj), DefaultName = "结点")]
    public List<INamedObject> MyProperty { get; set; } = new List<INamedObject>();

    public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
    {
        return new ExecuteResult();
    }
    
    public override CommandScope GetCommandScope()
    {
        return CommandScope.ExecutableInServer;
    }
}

public class MyObj : ObjectPropertyBase, INamedObject
{
    public string Name { get; set; }
    public string SubProperty1 { get; set; }
    public string SubProperty2 { get; set; }
    public string SubProperty3 { get; set; }
    public string SubProperty4 { get; set; }
}

ListProperty Vs ObjectListProperty

ListPropertyAttributeObjectListPropertyAttribute解决的是完全相同的问题,只是表现方式不同:

  • ObjectListPropertyAttribute 更适合项目子属性比较多的情况
  • ListProperty则在子属性比较少的时候比较适用

更新: 2024-02-28 10:51:03
原文: https://www.yuque.com/robert-bh51n/ea8l6c/svzhitp6smcdvtzm