CodeFluent Aspect: Как настроить ввод DropDown со свойствами объекта
Я разрабатываю аспект полнотекстового индекса и дошел до того, что я могу указать свойство, которое будет полнотекстовым индексом.
Однако следующее, что я хочу сделать, - это указать в синтаксисе полнотекстового индекса SQL "TYPE COLUMN xx", где "xx" - другое свойство того же объекта.
В связи с этим я хотел бы спросить аспекты CodeFluent, как мне настроить раскрывающийся список всех других постоянных свойств для текущей сущности для входных данных аспекта?
Вот код 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>");
}
Это дает мне "текстовое поле". То, что я хочу, это раскрывающийся список других свойств той же сущности.
Редактировать один:
Я пытался использовать 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>");
}
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.dll
а также CodeFluent.Model.dll
(в общем из C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler
).
Вам нужно будет скопировать ClassLibrary1.dll
который содержит этот конвертер в Visual Studio, откуда IDE может загрузить его, например, в C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
для Visual Studio 2015.
Обратите внимание: если вы определяете свой аспект в коде, вы можете поместить этот класс конвертера в ту же DLL, но вам всегда нужно будет копировать его в каталог Visual Studio.
Перезапустите Visual Studio, и вы должны увидеть что-то подобное в сетке свойств Visual Studio:
Как указано в комментариях, вы также можете создать UITypeEditor, используя тот же принцип, если вам нужно более сложное редактирование (и использовать ' editorTypeName
"Атрибут XML вместо" typeConverterTypeName
атрибута), но он не нужен для списка строк.