CodeFluent方面:如何使用实体属性设置DropDown输入

时间:2016-04-26 06:32:19

标签: codefluent aspects

我正在开发一个全文索引方面,我已经达到了可以将属性指定为全文索引的程度。

但是,我要做的下一件事是在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 Image of Aspect Inputs

编辑一个:

我尝试使用UITypeEditor来制作下拉菜单,但它似乎没有用。 “类型列”显示为灰色,并且有一个黑框。

Image of Type Editor Error

我可能做错了。

我的自定义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>");
        }

1 个答案:

答案 0 :(得分: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.dllCodeFluent.Model.Common.dllCodeFluent.Model.dll(通常来自C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler)。

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

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

重新启动Visual Studio,您应该在Visual Studio属性网格中看到类似的内容:

enter image description here

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