Back to Devexpress

How to: Add Custom Menu Items (Spelling Suggestions) to the Context Menu

windowsforms-5815-controls-and-libraries-rich-text-editor-examples-ui-customization-how-to-add-custom-menu-items-spelling-suggestions-to-the-context-menu.md

latest5.6 KB
Original Source

How to: Add Custom Menu Items (Spelling Suggestions) to the Context Menu

  • Nov 28, 2023
  • 3 minutes to read

This article demonstrates how you can modify the context menu of the XtraRichEdit control, by specifically adding a new item to it. To accomplish this, handle the RichEditControl.PopupMenuShowing event and use the PopupMenuShowingEventArgs.Menu argument’s property to access menu items.

The RichEditControl.PopupMenuShowing event is handled to insert new menu items, which are the suggested replacement words for the word where the caret is located. To obtain a list of suggestions, the ISpellChecker.GetSuggestions method of the XtraSpellChecker is used. When a menu item representing a suggested word is clicked, the SubDocument.Replace method substitutes the misspelled word for the selected suggestion.

csharp
using DevExpress.Utils.Menu;
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
using DevExpress.XtraRichEdit.Menu;
using DevExpress.XtraSpellChecker;

private void richEditControl1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
{
    if (spellChecker1.SpellCheckMode == SpellCheckMode.OnDemand)
    {
        DocumentPosition pos = richEditControl1.Document.CaretPosition;
        int wordEnd = GetWordEndIndex(pos);
        int wordStart = GetWordStartIndex(pos);
        if (wordEnd <= wordStart)
            return;
        DocumentRange range = richEditControl1.Document.CreateRange(wordStart, wordEnd - wordStart);
        string word = richEditControl1.Document.GetText(range);
        if (spellChecker1.IsMisspelledWord(word, spellChecker1.Culture))
            CreateMenuItems(e.Menu, range, word);
    }
}

void CreateMenuItems(RichEditPopupMenu menu, DocumentRange range, string word) {
    SuggestionCollection suggestions = this.spellChecker1.GetSuggestions(word);
    int count = suggestions.Count;
    if (count > 0) {
        int lastIndex = Math.Min(count - 1, 5);
        for (int i = lastIndex; i >= 0; i--) {
            SuggestionBase suggestion = suggestions[i];
            SuggestionMenuItem item = 
                new SuggestionMenuItem(this.richEditControl1.Document, suggestion.Suggestion, range);
            item.Image = RichEditPopupMenuExample.Properties.Resources.suggestion;
            menu.Items.Insert(0, item);
        }
    }
    else {
        DXMenuItem emptyItem = new DXMenuItem("no spelling suggestions");
        emptyItem.Enabled = false;
        menu.Items.Insert(0, emptyItem);
    }
}

public class SuggestionMenuItem : DXMenuItem {
    readonly Document document;
    readonly DocumentRange range;

    public SuggestionMenuItem(Document document, string suggestion, DocumentRange range)
        : base(suggestion) {
        this.document = document;
        this.range = range;
    }

    protected override void OnClick() {
        document.Replace(range, Caption);
    }
}
vb
Imports DevExpress.Utils.Menu
Imports DevExpress.XtraRichEdit
Imports DevExpress.XtraRichEdit.API.Native
Imports DevExpress.XtraRichEdit.Menu
Imports DevExpress.XtraSpellChecker

Private Sub richEditControl1_PopupMenuShowing(ByVal sender As Object, _
ByVal e As PopupMenuShowingEventArgs)
    If spellChecker1.SpellCheckMode = SpellCheckMode.OnDemand Then
        Dim pos As DocumentPosition = richEditControl1.Document.CaretPosition
        Dim wordEnd As Integer = GetWordEndIndex(pos)
        Dim wordStart As Integer = GetWordStartIndex(pos)
        If wordEnd <= wordStart Then
            Return
        End If
        Dim range As DocumentRange = _
richEditControl1.Document.CreateRange(wordStart, wordEnd - wordStart)
        Dim word As String = richEditControl1.Document.GetText(range)
        If spellChecker1.IsMisspelledWord(word, spellChecker1.Culture) Then
            CreateMenuItems(e.Menu, range, word)
        End If
    End If
End Sub

Private Sub CreateMenuItems(ByVal menu As RichEditPopupMenu, ByVal range As DocumentRange, ByVal word As String)
    Dim suggestions As SuggestionCollection = Me.spellChecker1.GetSuggestions(word)
    Dim count As Integer = suggestions.Count
    If count > 0 Then
        Dim lastIndex As Integer = Math.Min(count - 1, 5)
        For i As Integer = lastIndex To 0 Step -1
           Dim suggestion As SuggestionBase = suggestions(i)
           Dim item As New SuggestionMenuItem(Me.richEditControl1.Document, suggestion.Suggestion, range)
           item.Image = My.Resources.suggestion
           menu.Items.Insert(0, item)
        Next i
    Else
        Dim emptyItem As New DXMenuItem("no spelling suggestions")
        emptyItem.Enabled = False
        menu.Items.Insert(0, emptyItem)
    End If
End Sub

Public Class SuggestionMenuItem
    Inherits DXMenuItem
    Private ReadOnly document As Document
    Private ReadOnly range As DocumentRange

    Public Sub New(ByVal document As Document, ByVal suggestion As String, ByVal range As DocumentRange)
        MyBase.New(suggestion)
        Me.document = document
        Me.range = range
    End Sub

    Protected Overrides Sub OnClick()
        document.Replace(range, Caption)
    End Sub
End Class