ScintillaNet in WPF

When I have started working on ScintillaNET in WPF, I have faced many difficulties. I have searched long and very hard across the internet for a simple examples using ScintillaNET. It was really very hard to find appropriate examples which can fulfill my requirements. Then I have done things with detailed explorations and sometimes hits and tried. So I am posting all my working examples here so that it can be helpful to others also.

Scintilla is a free source code editing component. It comes with complete source code and a license that permits use in any free project or commercial product.

Scintilla is a free-library that provides text-editing functions, with an emphasis on advanced features for source code editing. SciTE (cross-platform), Geany (cross-platform), Notepad (Windows), and Notepad2 (Windows) are examples of standalone editors based on Scintilla.

Apply Style on particular lines Using ScintillaNet

_scintilla.Styles[2].ForeColor = System.Drawing.Color.Red;

_scintilla.Styles[2].Underline = true;

_scintilla.Styles[2].Bold = true;

_scintilla.Styles[2].Font = new Font("Times New Roman", 14, FontStyle.Italic);

var lengthOfLine = _scintilla.NativeInterface.LineLength(4);

var startPosOfLine = _scintilla.NativeInterface.PositionFromLine(4);

_scintilla.GetRange(startPosOfLine, startPosOfLine lengthOfLine).SetStyle(2);

 


Autocomplete Using ScintillaNet 

AutoComplete

private void ScintillaOnKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{

var scintilla = sender as Scintilla;

if (e.KeyChar == ' ') return;

var pos = scintilla.NativeInterface.GetCurrentPos();

var word = scintilla.GetWordFromPosition(pos);

if (word == string.Empty) return;

var list = _autocompleteList.FindAll(item => item.StartsWith(word));

if (list.Count > 0)

scintilla.AutoComplete.Show(list);

else

scintilla.AutoComplete.Cancel();

}

 

Please note that you have to add all the keywords in AutoComlete list of Scintilla for working this example. You can use config file or you can directly insert keywords into Scintilla Autocomplete list.

 

Draw Red Squiggly spell check line Using ScintillaNet 

SquiggleLine

_scintilla.Indicators[0].Style = IndicatorStyle.Squiggle;

_scintilla.Indicators[0].Color = System.Drawing.Color.Red;

var range = _scintilla.GetRange(0, _scintilla.Text.Length - 1);

range.ClearIndicator(0);

Range r = _scintilla.GetRange(7, 15);

r.SetIndicator(0);


Highlight Matched Words Using ScintillaNet 

Highlight Matched Words

private void ScintillaOnSelectionChanged(object sender, EventArgs e)
{

_scintilla.Indicators[1].Style = IndicatorStyle.RoundBox;

_scintilla.Indicators[1].Color = System.Drawing.Color.SpringGreen;

var range = _scintilla.GetRange(0, _scintilla.Text.Length - 1);

range.ClearIndicator(1);

if (_scintilla.Selection.Start != _scintilla.Selection.End)
{

string selectedWord = _scintilla.Selection.Text;

_scintilla.FindReplace.Flags = SearchFlags.WholeWord;

IList<Range> ranges = _scintilla.FindReplace.FindAll(selectedWord);

foreach (var r in ranges) { r.SetIndicator(1); }
}

}

Folding Feature Using ScintillaNet in WPF

folding in ScintillaNet in WPF

private readonly 
Dictionary<string, string> dict = new Dictionary<string, string>{ {"if", "endif"}, 
{"for", "next"},{"while", "endwhile"},{"do", "loop"}, {"else", "endif"}, {"elseif", "endif"}};

private readonly Regex exp = new Regex(@"b(if|for|while|do|else|elseif|region)b");

 

private void SetFolding(Scintilla scintilla)
{
var folding = new List();
var currentLevel = 1024;
var keywordStack = new Stack();

foreach (Line line in scintilla.Lines)
{
var match = exp.Match(line.Text);
if (match.Success)
{
var key = new Keyword { Else = (match.Value == “else” || match.Value == “elseif”), Value = dict[match.Value] };
keywordStack.Push(key);
folding.Add( new LineOptions { IsFoldPoint = true, Level = currentLevel, Number = line.Number });
currentLevel ;
}
elseif (keywordStack.Count != 0 &amp;amp;amp;&amp;amp;amp; line.Text.Contains(keywordStack.Peek().Value))
{
if (keywordStack.Peek().Else)
{
keywordStack.Pop();
currentLevel–-;
}
keywordStack.Pop();
currentLevel–-;
folding.Add( new LineOptions { IsFoldPoint = false, Level = currentLevel, Number = line.Number });
}
else
{
folding.Add(new LineOptions { IsFoldPoint = false, Level = currentLevel, Number = line.Number });
}
}

foreach (var lineConfig in folding)
{
scintilla.Lines[lineConfig.Number].IsFoldPoint = lineConfig.IsFoldPoint;
scintilla.Lines[lineConfig.Number].FoldLevel = lineConfig.Level;
}
}

public class LineOptions
{
public int Level { get; set; }
public bool IsFoldPoint { get; set; }
public int Number { get; set; }
}

public class Keyword
{
public bool Else { get; set; }
public string Value { get; set; }
}

 

 Highlight particular line Using ScintillaNet 

Marker

private Marker marker;
private void AddMarker(Scintilla scintilla, int lineNumber)
{
marker = scintilla.Markers[0];
marker.Symbol = MarkerSymbol.Background;
marker.BackColor = Color.Yellow;

scintilla.Lines[lineNumber - 1].AddMarker(marker);
}

private void DeleteMarker(Scintilla scintilla)
{
var lineCount = scintilla.Lines.Count;

for (var i = 0; i &amp;lt; lineCount; i )
{
//to clear the background color unset the marker
scintilla.Lines[i].DeleteAllMarkers();
}
}

 Context Menu on ScintillaNet 

ContextMenu

private ToolStripMenuItem menuItemCut;

private ToolStripMenuItem menuItemCopy;

private ToolStripMenuItem menuItemPaste;

private ToolStripMenuItem menuItemFind;

private ToolStripMenuItem menuItemFindReplace;

private ToolStripMenuItem menuItemGotoLine;

private ToolStripMenuItem menuItemInsert;

private ToolStripMenuItem [] subMenuItemsInsert;

private void ContextMenuForScintilla(Scintilla initScintilla)
{

var contextMenu = _scintilla.ContextMenuStrip = new ContextMenuStrip();

menuItemCut = new ToolStripMenuItem(&amp;quot;Cut&amp;quot;, null, (s, ea) =&amp;gt; _scintilla.Clipboard.Cut());

contextMenu.Items.Add(menuItemCut);

menuItemCopy = new ToolStripMenuItem(&amp;quot;Copy&amp;quot;, null, (s, ea) =&amp;gt; _scintilla.Clipboard.Copy());

contextMenu.Items.Add(menuItemCopy);

menuItemPaste = new ToolStripMenuItem(&amp;quot;Paste&amp;quot;, null, (s, ea) =&amp;gt; _scintilla.Clipboard.Paste());

contextMenu.Items.Add(menuItemPaste);

contextMenu.Items.Add(new ToolStripSeparator());

menuItemFind = new ToolStripMenuItem(&amp;quot;Find&amp;quot;, null, (s, ea) =&amp;gt; FindAndReplaceInteraction(FindReplaceEventArgs.CommandActions.Find, ea)) { ShortcutKeys = Keys.Control | Keys.F };

contextMenu.Items.Add(menuItemFind);

menuItemFindReplace = new ToolStripMenuItem(&amp;quot;Find And Replace&amp;quot;, null, (s, ea) =&amp;gt; FindAndReplaceInteraction FindReplaceEventArgs.CommandActions.FindAndReplace, ea)) { ShortcutKeys = Keys.Control | Keys.H };

contextMenu.Items.Add(menuItemFindReplace);

menuItemGotoLine = new ToolStripMenuItem(&amp;quot;Go To Line&amp;quot;, null, (s, ea) =&amp;gt; FindAndReplaceInteraction(FindReplaceEventArgs.CommandActions.GoToLine, ea)) { ShortcutKeys = Keys.Control | Keys.G };

contextMenu.Items.Add(menuItemGotoLine);

contextMenu.Items.Add( new ToolStripSeparator());

subMenuItemsInsert = new ToolStripMenuItem[2];

subMenuItemsInsert[0] = new ToolStripMenuItem(&amp;quot;Keyword&amp;quot;, null, (s, ea) =&amp;gt; ShowKeywordBrowserCommand.Execute(true)) { ShortcutKeys = Keys.Control | Keys.Q };

subMenuItemsInsert[1] = new ToolStripMenuItem(&amp;quot;Functions&amp;quot;, null, (s, ea) =&amp;gt; ShowFunctionsCommand.Execute(true));

menuItemInsert = new ToolStripMenuItem(&amp;quot;Insert&amp;quot;, null, initsubMenuItemsInsert);

contextMenu.Items.Add(menuItemInsert);
}

// This Event will open ContextMenu.
private void _initScintilla_MouseDown(object sender, MouseEventArgse)
{
if (e.Button == MouseButtons.Right)
{
initmenuItemCut.Enabled = _initScintilla.Clipboard.CanCut;

initmenuItemCopy.Enabled = _initScintilla.Clipboard.CanCopy;

initmenuItemPaste.Enabled = _initScintilla.Clipboard.CanPaste;
}
}

Written by 

19 thoughts on “ScintillaNet in WPF

  1. The folding doesn’t work…
    It gives an error about var match = exp.Match(line.Text);
    exp is not defined…

    Can you please post a working example?

      1. Well I’ve copy your code and tested it, but it still doesn’t do anything.
        Btw, you’ve a little type {“do”, “loop”, should be {“do”, “loop”},

        Is there anything else that I’ve missed?
        Maybe you can email me a source code of a working example?
        I really want to use the folding option but couldn’t make it work and there is not much information about it when I google.

        Thanks

    1. This is working example. i am giving you more information from where you have to call this function.

      private void ScintillaOnTextChanged(object sender, EventArgs e)
      {
      SetFolding(scintilla);
      }

      Still you are facing problem then send me your sample..i will analyse and try to solve the issues.

      Thanks,

      Vipin K. Yadav

      1. I didn’t get a response from you…
        I’ve already sent you an example.

        Can you please test it and tell me what am I doing wrong?

  2. That it was relaxing to identify a Honest Kern overview, then stuck
    to the basic trail to exactly what this unique charismatic person is required
    to suggest in his or her website. There is much to learn about if you want to make money
    with your own programs, or services. Two areas of this software
    are specialized in finding income generating markets to operate in.

  3. hai vipin sir,
    it is nice post i tried all and working fine but i am getting error in last example i.e Context Menu on ScintillaNet,
    first i tried only copy and paste and cut its works great, after when i trying to insert Find and replace i am getting error.
    code which throws error is “FindAndReplaceInteraction FindReplaceEventArgs.CommandActions.FindAndReplace, ea)) { ShortcutKeys = Keys.Control | Keys.H };”

    error message i am getting is
    Error 1 Cannot convert lambda expression to type ‘System.Windows.Forms.ToolStripItem[]’ because it is not a delegate typeMainWindow.xaml.cs

Leave a Reply

Your email address will not be published. Required fields are marked *