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

  • 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.

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, 
    DevExpress.XtraRichEdit.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);
    }
}