Custom Autocompletion - desjarlais/Scintilla.NET GitHub Wiki
What Is This For?
Basically, a lot of people already know that Scintilla's auto-complete is pretty basic and simply just lacking a lot of features.
So, I will be explaining here on how to add the AutoCompleteMenu to ScintillaNET.
For people who don't know it, here are some images explaining its abilities:
NOTE: the images shown are for regular TextBoxes, but it'll work just exactly for Scintilla.
Adding the Library to Your Project
Downloading:
To save you time, I have created my own repository on GitHub with a wrapper already made for you :)
You can download the compiled library from NuGet. The package name is AutoCompleteMenu-ScintillaNET
.
If you want to browse the code, the repository is here: https://github.com/JohnyMac/AutoCompleteMenu-ScintillaNET.
Binding it to ScintillaNET
Next, we want to make it work with Scintilla.
Simply, go to your Form_Load
event or wherever you want and add this: AutoCompleteMenu.TargetControlWrapper = New ScintillaWrapper(scintilla1);
Then the wrapper will do all the rest. All you need to do now is add the keywords.
Adding Keywords:
There are several methods for doing so, and it depends on what you need it for.
Method 1: (Static)
This is useful if the keywords are basically static and not added on run-time. To do this, simply edit the property Items
found in the AutoCompleteMenu.
Method 2: (Static but on runtime)
If you want to change the keywords during runtime, you can use this. However, don't use this if the keywords are dynamic. Only use it for static because there is a better way.
Here is an example:
string[] snippets = { "Whatever", "Bla", "Another_bla", "HEY" };
private void BuildAutocompleteMenu()
{
var items = new List<AutocompleteItem>();
foreach (var item in snippets)
items.Add(new SnippetAutocompleteItem(item) { ImageIndex = 1 });
//set as autocomplete source
autocompleteMenu1.SetAutocompleteItems(items);
}
Method 3: (Static but object oriented)
If you want to basically just store objects instead of strings. For example, if you want to store the ToolTip info alongside with the items.
Simply create an object that inherits the AutocompleteItem. For example:
internal class EmailSnippet : AutocompleteItem
{
public EmailSnippet(string email): base(email)
{
ImageIndex = 0;
ToolTipTitle = "Insert email:";
ToolTipText = email;
}
public override CompareResult Compare(string fragmentText)
{
if (fragmentText == Text)
return CompareResult.VisibleAndSelected;
if (fragmentText.Contains("@"))
return CompareResult.Visible;
return CompareResult.Hidden;
}
}
Method 4: (Dynamic)
This is very useful when the list shouldn't be the same each time. For example, if you parse the code and the auto-complete is shown depending on that.
Simply, you create a class that implements IEnumerable<AutocompleteItem>
and then use that in the function SetAutocompleteItems
once. For example:
internal class DynamicCollection : IEnumerable<AutocompleteItem>
{
public IEnumerator<AutocompleteItem> GetEnumerator()
{
return BuildList().GetEnumerator();
}
private IEnumerable<AutocompleteItem> BuildList()
{
//find all words of the text
var words = new Dictionary<string, string>();
foreach (Match m in Regex.Matches(tb.Text, @"\b\w+\b"))
words[m.Value] = m.Value;
//return autocomplete items
foreach(var word in words.Keys)
yield return new AutocompleteItem(word);
}
}
...
autocompleteMenu1.SetAutocompleteItems(new DynamicCollection(tb));
Here you don't do SetAutocompleteItems
each time you parse the codem but simply modify the collection and it will do the rest.
Credits and Sources
First of all, great thanks to Pavel Torgashov who created this library.
The original post and the source of everything: http://www.codeproject.com/Articles/365974/Autocomplete-Menu. Also, that topic can be very helpful if you need any help in the library too.