3

我正在开发全文索引方面,并且已经到了可以将属性指定为全文索引的地步。

但是,接下来我要做的是在 SQL 全文索引语法中指定“TYPE COLUMN xx”,其中“xx”是同一实体的另一个属性。

为此,我想问一下 CodeFluent Aspects,如何设置它以提供当前实体的所有其他持久属性的下拉列表以用于方面输入?

这是我目前拥有的 CodeFluent Aspect XML 代码:

        static FullTextIndexing()
        {
            Descriptor = new XmlDocument();
            Descriptor.LoadXml(
@"<cf:project xmlns:cf='http://www.softfluent.com/codefluent/2005/1' defaultNamespace='FullTextIndexing'>
    <cf:pattern name='Full Text Indexing' namespaceUri='" + NamespaceUri + @"' preferredPrefix='ftind' step='Tables'>
        <cf:message class='_doc'>CodeFluent Full Text Indexing Aspect</cf:message>
        <cf:descriptor name='fullTextIndex'
            typeName='boolean'
            category='Full Text Index'
            targets='Property'
            defaultValue='false'
            displayName='Full-Text Index'
            description='Determines if property should be a full text index.' />
        <cf:descriptor name='fullTextIndexTypeColumn'
            typeName='text'
            category='Full Text Index'
            targets='Property'
            displayName='Type Column'
            description='The type column for the full text index.' />
    </cf:pattern>
</cf:project>");
        }

这给了我一个“文本框”。我想要的是同一实体的其他属性的下拉列表。

方面输入的 CodeFluent 图像

编辑一:

我尝试使用 UITypeEditor 进行下拉,但它似乎不起作用。“类型列”是灰色的,并且有一个黑框。

类型编辑器错误的图像

我可能做错了什么。

我的自定义 UITypeEditor 类如下:

namespace CodeFluent.Aspects.AspectEditors
{
    public class OtherPropertyDropDownEditor : UITypeEditor
    {
        private IWindowsFormsEditorService _editorService;
        
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            // drop down mode (we'll host a listbox in the drop down)
            return UITypeEditorEditStyle.DropDown;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            _editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

            // use a list box
            ListBox lb = new ListBox();
            lb.SelectionMode = SelectionMode.One;
            lb.SelectedValueChanged += delegate
            {
                // close the drop down as soon as something is clicked
                _editorService.CloseDropDown();
            };

            // use the Property.Name property for list box display
            lb.DisplayMember = "Name";

            // this is how we get the list of possible properties
            IEnumerable<Property> otherProperties = GetOtherPersistentProperties(context);
            foreach (Property otherProperty in otherProperties)
            {
                int index = lb.Items.Add(otherProperty);
                if (otherProperty.Equals(value))
                {
                    lb.SelectedIndex = index;
                }
            }


            // show this model stuff
            _editorService.DropDownControl(lb);
            if (lb.SelectedItem == null) // no selection, return the passed-in value as is
                return value;

            return lb.SelectedItem;
        }

        private IEnumerable<Property> GetOtherPersistentProperties(ITypeDescriptorContext context)
        {
            // context is of type ITypeDescriptorContext, got from EditValue overloads.
            var property = TypeNameEditor.GetObject<Property>(context);

            IEnumerable<Property> otherEntityProperties = null;
            if (property != null && property.Entity != null)
                otherEntityProperties = property.Entity.Properties.Where(p => p.IsPersistent && p != property);
            return otherEntityProperties;
        }
    }
}

到目前为止,我拥有的 XML 是这样的。注意我添加了“editorTypeName”。

        static FullTextIndexing()
        {
            Descriptor = new XmlDocument();
            Descriptor.LoadXml(
@"<cf:project xmlns:cf='http://www.softfluent.com/codefluent/2005/1' defaultNamespace='FullTextIndexing'>
    <cf:pattern name='Full Text Indexing' namespaceUri='" + NamespaceUri + @"' preferredPrefix='ftind' step='Tables'>
        <cf:message class='_doc'>CodeFluent Full Text Indexing Aspect</cf:message>
        <cf:descriptor name='fullTextIndex'
            typeName='boolean'
            category='Full Text Index'
            targets='Property'
            defaultValue='false'
            displayName='Full-Text Index'
            description='Determines if property should be a full text index.' />
        <cf:descriptor name='fullTextIndexTypeColumn'
            category='Full Text Index'
            targets='Property'
            editorTypeName='CodeFluent.Aspects.AspectEditors.OtherPropertyDropDownEditor, CodeFluent.Aspects.AspectEditors.OtherPropertyDropDownEditor, CodeFluent.Aspects.AspectEditors'
            displayName='Type Column'
            description='The type column for the full text index.'
            />
    </cf:pattern>
</cf:project>");
        }
4

1 回答 1

1

您可以做的是向您的描述符添加一个 xml 属性以定义自定义TypeConverter类型名称,例如:

<cf:descriptor name='fullTextIndexTypeColumn'
            typeName='text'
            category='Full Text Index'
            targets='Property'
            displayName='Type Column'
            description='The type column for the full text index.'
            typeConverterTypeName='ClassLibrary1.MyAspectConverter, ClassLibrary1'
            />

然后你需要实现 MyAspectConverter 类(这里在 ClassLibrary1.dll 中),例如这样:

public class MyAspectConverter : StringConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var list = new List<string>();
        var property = TypeNameEditor.GetObject<Property>(context);
        if (property != null && property.Entity != null)
        {
            list.AddRange(property.Entity.Properties.Where(p => p.IsPersistent).Select(p => p.Name));
        }
        return new StandardValuesCollection(list);
    }
}

ClassLibrary1 需要引用CodeFluent.Runtime.dll,CodeFluent.Model.Common.dllCodeFluent.Model.dll(通常来自C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler)。

您需要将ClassLibrary1.dll包含此转换器的文件复制到 IDE 可以从中加载它的 Visual Studio,例如在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDEVisual Studio 2015 中。

请注意,如果您在代码中定义方面,则可以将此转换器类放在同一个 DLL 中,但您始终需要将其复制到 Visual Studio 目录中。

重新启动 Visual Studio,您应该会在 Visual Studio 属性网格中看到如下内容:

在此处输入图像描述

如评论中所述,如果您需要更高级的编辑(并使用 ' editorTypeName' XML 属性而不是 ' typeConverterTypeName' 属性),也可以使用相同的原理创建 UITypeEditor ,但字符串列表不需要它。

于 2016-04-27T23:17:57.797 回答