我正在使用WinForms文本框和Fast Colored TextBox控件的组合开发应用程序(语法突出显示)来编辑用html标记和其他xml标记标记的字符串,我已经在使用Pavel Torgashov的自动完成菜单在某些文本框中提供非xml建议。我希望在键入“〈"时使用自动完成菜单来建议xml标记,并且建议属性名称和值,但仅当carot位于建议适用的标记内时。我还希望自动建议关闭下一个需要关闭的打开标记。
在阅读了CodeProject page for the autocomplete menu上的许多评论后,我看到其他人也问了同样的问题,但没有提供解决方案。
如何做到这一点?
2条答案
按热度按时间nwsw7zdq1#
自动建议属性名称和值
最后两个类别提供属性名称和值的建议。属性名称建议可以使用
string[] AppliesToTag
属性指定要套用到哪些标签。TagName扩充方法是用来在Compare方法期间补充文字片段信息,以实作此筛选。属性值建议子类别衍生自MethodSnippetAutocompleteItem,使用基底类别上的
string[] AppliesTo
属性筛选出不适用于目前属性的值建议,并提供string[] AppliesToTag
筛选本身。使用此类,您还可以指定在插入建议后,标记是否应作为一个完整的开始标记后跟一个相应的结束标记来结束,或者标记是否应作为一个完整的单个标记来结束(例如,
<tag />
)。如果未进行这两种选择,则在插入建议后,标记将保持不完整。wj8zmpe12#
PavelTorgashov的Autocomplete Menu的工作原理是识别插入符号周围的文本片段,并使用正则表达式定义片段中包含哪些字符,从而提供建议。但是我能想到的使xml建议很好地工作的最简单的方法需要一个不同的搜索模式,该模式定义了插入符号之前要包含的字符,而不是包括在插入符号之后。这是一个要做的简单修改,也是我发现通过对Autocomplete Item进行子类化来实现所有必需的xml功能所必需的唯一修改。
自动完成功能表.cs修改
以下列两个属性取代AutocompleteMenu.cs中的SearchPattern属性,在建构函式中加入预设值,并相应地调整使用SearchPattern(虽然是间接使用)的方法:
在此之后,下一个挑战是使自动完成项能够理解插入符号何时位于标记内,以及该标记的名称(如果已键入)。用于理解直接片段之前的文本框中的文本如何与当前适用的建议相关的该功能可以通过使用应用于ITextBoxWrapper接口的扩展方法来添加,Torgashov使用该接口来表示文本框中,而不是对其AutocompleteMenu类本身进行任何进一步的修改。
自动完成扩展代码列表
在这里,我将这些扩展方法与解决方案中使用的其他方法组合在一起。首先,几个非常简单的扩展使代码的其余部分更具可读性:
上面的最后一个扩展方法在下面的两个扩展方法中与regex结合使用。regex搜索模式区分开始和结束标记,但是当开始标记没有属性时,它会捕获开始标记中“〉”之前的最后一个字符,作为表示标记名的regex组的一部分,这使得使用regex区分开始标记和空标记变得很难甚至不可能。而使用这种扩展方法则非常简单。
这个next扩展方法从Torgashov的snippet autocomplete项中复制代码,以便可以将该功能包含在其他AutocompleteItem子类中,而不必从其snippet autocomplete项中派生。
接下来的两个扩展方法为ITextBoxWrapper添加了重要的功能,以便了解插入符号是否在标记内,如果是,则了解标记的名称。
最后两个ITextBoxWrapper扩展方法提供了确定建议结束标记的开始标记的替代方法(即,如果用户键入了
"<p>This is a sentence, but not a closed paragraph.<"
,则建议插入"/p>
)。第一种方法比较简单,它只在本地搜索,无法在插入符号之前的任何结束标记之前生成开始标记的建议。(换句话说,如果单词“句子”在前一示例中加粗,它将在
"</b>
处停止搜索并返回string.Empty。)第二个将尝试一直搜索到文本框文本的开头。在我开发的应用程序中,有许多文本框,但每个文本框通常只有几个句子或几个段落的内容,所以我没有机会评估第二种方法在其中包含大型xml或html文档的文本框中的性能。(在我的应用程序中,标记大多数是html,因此这里的默认值不区分大小写,但是如果需要更严格的XML标准遵从性,则可以在第二个方法中向该方法传递一个区分大小写的字符串比较器。)我几乎可以肯定,StackOverflow上的某个人将能够提出一个格式良好的XML文档的示例,对于该文档,如果插入符号位于特定位置,上述算法将产生错误的建议。我很想知道人们提出了哪些产生错误建议的示例,以及他们如何建议改进该算法。
方法代码段自动完成项
我的大多数xml自动完成项都建立在Torgashov开发的自动完成项的基础上,该自动完成项在用户在表示编程语言代码的文本框中键入句点后建议方法名。我将他的MethodAutocompleteItem中的代码复制到我自己的AutocompleteItem子类中,以便进行一些改进。
第一个改进是指定“枢纽”字符,将一个符号(例如类名)与第二个符号(例如方法名)分隔开。对于表示xml标记名的建议,枢纽字符将变为“〈",而对于表示标记内xml属性值的建议,枢纽字符将变为“="。
与xml建议相关的另一个改进是添加了
string[] AppliesTo
属性。如果设置了该属性,则仅当透视字符之前的部分位于AppliesTo数组中时,才会显示建议。这允许仅在用户键入适用的属性名称后才建议属性值。Compare覆盖还将当前片段中透视字符之后的部分存储在受保护的字段中,以供覆盖IsAppliable方法的子类使用。
基于MethodSnippetAutocomplete和上面的扩展方法,使用相对简单的AutocompleteItem子类就可以很容易地满足xml建议要求。
自动建议完成当前标记,或为任意开始标记插入结束标记
AutocompleteItem的前两个面向XML的子类适用于任意标记,而不是专门适用于开发人员已将标记名称列为要建议的特定标记的标记。
第一种方法建议将当前in-progress标记作为开始标记/结束标记对完成,并通过上述扩展方法使用代码片段行为将插入符号放置在开始标记和结束标记之间。
第二个方法建议为下一个需要关闭的开始标记添加结束标记。它派生自MethodSnippetAutocompleteItem,以便在用户键入“〈"时出现。正如我上面提到的,我提供了两种不同的方法来确定为哪个标记插入结束标记。下面的类提供了这两种方法的语句:其中一个被注解掉。切换两个扩展方法中的哪一个被调用以使用另一个方法。
自动建议标记名称
下一个类派生自MethodSnippetAutocompleteItem以便在用户键入“〈"时建议特定的标记名。它被设计为与其他AutocompleteItem子类一起工作以实现完整标记的构造,而不是处理标记名本身以外的内容。如果标记名在末尾定义有空格,则在用户插入此建议后,将自动建议属性名称并以结束标记结束标记。如果不需要特定标记的属性建议,请省略空格。