Я ищу способ реализовать PropertyGrid, чтобы пользователь мог ввести каноническое значение или щелкнуть «<Expression ...>», чтобы перейти и написать выражение для оценки этого свойства.
BIDS SSRS позволяет пользователю сделать это, поэтому, например, когда в PropertyGrid создается раскрывающийся список для типа Color, используется следующий раскрывающийся список:
И для логического значения:
Где пользователь может щелкнуть Expression и перейти к построению выражения, которое будет оцениваться во время выполнения. У меня нет проблем с написанием построителя выражений и его синтаксическим анализом / оценкой во время выполнения, но мне неясен оптимальный способ кодирования этого по отношению к PropertyGrid.
В качестве тестового примера я использую свойство ReadOnly и изменил его с bool на объектный тип. Таким образом, он может принимать то, что вводит пользователь, то есть либо строку, представляющую логическое значение, либо объект типа Expression (класс, который я должен хранить выражения):
[DescriptionAttribute("Whether the user can edit the contents.")]
//[Editor(typeof(ExpressionPropertyEditor), typeof(UITypeEditor))]
[TypeConverterAttribute(typeof(ReadOnlyConverter))]
public object ReadOnly
{
get
{
try
{
bool bReadonly = false;
string cXmlPath = "";
cXmlPath = Helper.GetXmlModePathForRead(base.Xml, base.Frm.ModeCode);
if (!Dolphin.modGeneral.XMLGetValueBoolean(base.Globals, base.Xml, cXmlPath + "ReadOnly", ref bReadonly)) throw new Exception("Cannot get Readonly property from TEXTBOX control.");
return bReadonly.ToString();
}
catch (Exception ex)
{
base.Globals.Errs.Raise(ex);
throw ex;
}
}
set
{
frmExpressionEditor frm;
try
{
string cXmlPath = "";
switch ((string)value)
{
case "True":
case "False":
cXmlPath = Helper.GetXmlModePathForRead(base.Xml, base.Frm.ModeCode);
if (!Dolphin.modGeneral.XMLSetNode(base.Globals, base.Xml, cXmlPath + "ReadOnly", value.ToString())) throw new Exception("Cannot set Readonly property on TEXTBOX control.");
break;
case Consts.EXPRESSION_PROPERTY_NAME:
frm = new frmExpressionEditor();
if (!frm.EditExpression(value)) throw new Exception("Could not edit Expression correctly.");
break;
}
}
catch (Exception ex)
{
base.Globals.Errs.Raise(ex);
throw ex;
}
}
}
Обратите внимание, что в настоящее время хранение выполняется в XML-документе, который я могу изменить, а также приведенный выше код не полностью завершен.
Как лучше всего управлять этим с точки зрения PropertyGrid, значение в данном случае является логическим или выражением? В других случаях это может быть строка или выражение, строка или выражение.





На этот вопрос есть много ответов. Я бы создал класс Expression, например, с BooleanExpression и ColorExpression, производным от него, вместо использования объекта. А затем связал с ним UITypeEditor, как будто вы тестируете в комментариях. Опять же, вы можете создать базовый ExpressionEditor, который будет делать все это или несколько производных. Похоже, UITypeEditorEditStyle.DropDown хорошо подходит для того, что вы показываете выше.