By subclassing RapidSpellGUI, it is possible to modify standard behaviour and add new behavior. In this example we add undo functionality to RapidSpellGUI and then use this new RapidSpellGUI with RapidSpellDialog. Important note: this code is provided as-is, it should not be considered fully tested and is provided without any warranty. If you plan to use it for production you must fully test it! Step 1. add a new file to your project and paste this content C# using Keyoti.RapidSpell;using System;using System.Collections;using System.Drawing;using System.Windows.Forms;class CustomUserInterfaceFormProvider : IUserInterfaceFormProvider{ public IUserInterfaceForm CreateUserInterfaceForm(){ return new CustomGUI(); }} public class CustomGUI : RapidSpellGUI{ Button undoButton = new Button();RapidSpellChecker theCheckerEngine = null;ArrayList stateHistory; //retreives the CheckerEngine cast as RapidSpellChecker.RapidSpellChecker RSCEngine { get{ if(theCheckerEngine==null)theCheckerEngine = (RapidSpellChecker) CheckerEngine; return theCheckerEngine;} } protected override void Dispose(bool disposing){ undoButton.Click -= new EventHandler(Undo);base.Dispose(disposing);} /// <summary>/// Called when starting a text box/// </summary>public override void Check(){ //reset everythingtheCheckerEngine = null;stateHistory = new ArrayList();undoButton.Enabled = false;base.Check();} protected override void BuildGUI(){ base.BuildGUI();Size = new Size(Size.Width, Size.Height + 15);undoButton.Text = "Undo"; undoButton.Location = new Point(225, 220);undoButton.Size = this.defaultButtonSize;undoButton.TabIndex=8; undoButton.Click += new EventHandler(Undo);undoButton.Enabled = false;Controls.Add(undoButton); } protected override void Ignore(){ OnStateChange(Action.Ignore); base.Ignore();} protected override void IgnoreAll(){ OnStateChange(Action.IgnoreAll); base.IgnoreAll();} protected override void ChangeWord(){ OnStateChange(Action.Change); base.ChangeWord();} protected override void ChangeAll(){ OnStateChange(Action.ChangeAll); base.ChangeAll();} void OnStateChange(Action action){ stateHistory.Add( new State(this.theTextComponent.Text, action, theBadWord.StartPosition, theBadWord.GetWord(), this.subFromPosition,this.subToPosition,this.wrapped)); undoButton.Enabled = true;} void ApplyState(State state){ this.theTextComponent.Text = state.Text;this.RSCEngine.Check (state.Text.Substring(state.SubFromPosition, (state.SubToPosition-state.SubFromPosition)), state.CurrentWordPointer ); this.wrapped = state.Wrapped;this.subFromPosition = state.SubFromPosition;this.subToPosition = state.SubToPosition;} protected virtual void Undo(object sender, EventArgs e){ //get the state beforeState priorState = (State) stateHistory[stateHistory.Count-1]; if(priorState.LeaveAction == Action.IgnoreAll)this.RSCEngine.IgnoreList.Remove(priorState.LeaveActionWord);ApplyState(priorState); this.Resume();//remove the prior statestateHistory.RemoveAt(stateHistory.Count-1); if(stateHistory.Count==0)undoButton.Enabled = false; } class State{ /// <summary>/// The text in the text box./// </summary>public string Text;/// <summary>/// The action that caused this state to change./// </summary>public Action LeaveAction;/// <summary>/// The word associated with the action (ie. the ignored/added word)./// </summary>public string LeaveActionWord;/// <summary>/// Where in the text the engine has reached./// </summary>public int CurrentWordPointer;/// <summary>/// Where to spell checker will check to/// </summary>public int SubToPosition;/// <summary>/// Where to spell checker will check from/// </summary>public int SubFromPosition;/// <summary>/// Whether the check has wrapped/// </summary>public bool Wrapped;public State(string text, Action leaveAction, int currentWordPointer, string leaveActionWord, int subFromPosition, int subToPosition, bool wrapped){ this.Text = text;this.LeaveAction = leaveAction;this.CurrentWordPointer = currentWordPointer;this.LeaveActionWord = leaveActionWord;this.SubFromPosition = subFromPosition;this.SubToPosition = subToPosition;this.Wrapped = wrapped;} } enum Action{ Ignore, IgnoreAll, Change, ChangeAll } } VB.NET Imports Keyoti.RapidSpellImports SystemImports System.CollectionsImports System.DrawingImports System.Windows.Forms_ Class CustomUserInterfaceFormProviderImplements IUserInterfaceFormProviderPublic Function CreateUserInterfaceForm() As IUserInterfaceForm Implements IUserInterfaceFormProvider.CreateUserInterfaceFormReturn New CustomGUIEnd Function 'CreateUserInterfaceFormEnd Class 'CustomUserInterfaceFormProvider_ Public Class CustomGUIInherits RapidSpellGUIPrivate undoButton As New ButtonPrivate theCheckerEngine As RapidSpellChecker = NothingPrivate stateHistory As ArrayList'retreives the CheckerEngine cast as RapidSpellChecker.ReadOnly Property RSCEngine() As RapidSpellCheckerGetIf theCheckerEngine Is Nothing ThentheCheckerEngine = CType(CheckerEngine, RapidSpellChecker)End IfReturn theCheckerEngineEnd GetEnd Property Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)RemoveHandler undoButton.Click, AddressOf UndoMyBase.Dispose(disposing)End Sub 'Dispose '/ <summary>'/ Called when starting a text box'/ </summary>Public Overloads Overrides Sub Check()'reset everythingtheCheckerEngine = NothingstateHistory = New ArrayListundoButton.Enabled = FalseMyBase.Check()End Sub 'Check Protected Overrides Sub BuildGUI()MyBase.BuildGUI()Size = New Size(Size.Width, Size.Height + 15)undoButton.Text = "Undo" undoButton.Location = New Point(225, 220)undoButton.Size = Me.defaultButtonSizeundoButton.TabIndex = 8 AddHandler undoButton.Click, AddressOf UndoundoButton.Enabled = FalseControls.Add(undoButton) End Sub 'BuildGUI Protected Overrides Sub Ignore()OnStateChange(Action.Ignore) MyBase.Ignore()End Sub 'Ignore Protected Overrides Sub IgnoreAll()OnStateChange(Action.IgnoreAll) MyBase.IgnoreAll()End Sub 'IgnoreAll Protected Overrides Sub ChangeWord()OnStateChange(Action.Change) MyBase.ChangeWord()End Sub 'ChangeWord Protected Overrides Sub ChangeAll()OnStateChange(Action.ChangeAll) MyBase.ChangeAll()End Sub 'ChangeAll Sub OnStateChange(ByVal action As Action)stateHistory.Add( New State(Me.theTextComponent.Text, action, theBadWord.StartPosition, theBadWord.GetWord(), Me.subFromPosition, Me.subToPosition, Me.wrapped))undoButton.Enabled = TrueEnd Sub 'OnStateChange Sub ApplyState(ByVal state As State)Me.theTextComponent.Text = state.TextMe.RSCEngine.Check(state.Text.Substring(state.SubFromPosition, state.SubToPosition - state.SubFromPosition), state.CurrentWordPointer)Me.wrapped = state.WrappedMe.subFromPosition = state.SubFromPositionMe.subToPosition = state.SubToPositionEnd Sub 'ApplyState Protected Overridable Sub Undo(ByVal sender As Object, ByVal e As EventArgs)'get the state beforeDim priorState As State = CType(stateHistory((stateHistory.Count - 1)), State)If priorState.LeaveAction = Action.IgnoreAll ThenMe.RSCEngine.IgnoreList.Remove(priorState.LeaveActionWord)End IfApplyState(priorState) Me.Resume()'remove the prior statestateHistory.RemoveAt((stateHistory.Count - 1)) If stateHistory.Count = 0 ThenundoButton.Enabled = FalseEnd IfEnd Sub 'Undo_ Class State'/ <summary>'/ The text in the text box.'/ </summary>Public [Text] As String'/ <summary>'/ The action that caused this state to change.'/ </summary>Public LeaveAction As Action'/ <summary>'/ The word associated with the action (ie. the ignored/added word).'/ </summary>Public LeaveActionWord As String'/ <summary>'/ Where in the text the engine has reached.'/ </summary>Public CurrentWordPointer As Integer'/ <summary>'/ Where to spell checker will check to'/ </summary>Public SubToPosition As Integer'/ <summary>'/ Where to spell checker will check from'/ </summary>Public SubFromPosition As Integer'/ <summary>'/ Whether the check has wrapped'/ </summary>Public Wrapped As Boolean Public Sub New(ByVal [text] As String, ByVal leaveAction As Action, ByVal currentWordPointer As Integer, ByVal leaveActionWord As String, ByVal subFromPosition As Integer, ByVal subToPosition As Integer, ByVal wrapped As Boolean)Me.Text = [text]Me.LeaveAction = leaveActionMe.CurrentWordPointer = currentWordPointerMe.LeaveActionWord = leaveActionWordMe.SubFromPosition = subFromPositionMe.SubToPosition = subToPositionMe.Wrapped = wrappedEnd Sub 'NewEnd Class 'State_ Enum ActionIgnore IgnoreAll Change ChangeAll End Enum 'ActionEnd Class 'CustomGUI this file includes a subclass of RapidSpellGUI which adds an undo button and methods to support it, it overrides the ignore/change actions to record an undo history. Step 2. Use this with RapidSpellDialog by specifying a UserInterfaceFormProvider C# private void OnCheckSpellingClicked(object sender, System.EventArgs e) { //Make RapidSpellDialog use our custom user interface this.rapidSpellDialog1.UserInterfaceFormProvider = new CustomUserInterfaceFormProvider(); this.rapidSpellDialog1.Check();} VB.NET Private Sub CheckSpelling_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click 'Make RapidSpellDialog use our custom user interface (as returned by CustomUserinterfaceFormProvider) Me.RapidSpellDialog1.UserInterfaceFormProvider = New CustomUserInterfaceFormProvider Me.RapidSpellDialog1.Check()End Sub To understand more about how this works we suggest you also see the CustomGUI example project, and the user guide section on custom user interfaces. If you experience any problems with this code, or have questions - please email support@keyoti.com |