RapidSpell Desktop and Thesaurus Desktop Integration With TX Text Control v14
This article is for TX v14 only, for TX v13 and earlier, please see this article.
Integration of RapidSpell and Thesaurus with TX Text Control can be as simple as dragging controls on to the Form and setting two properties in the property editor - however, TX Text Control is a powerful word processor component, and full integration of spell checking can be a little more complex with some subtle points to consider. This article intends to show how to achieve full integration, and will address commonly asked questions about this subject.
To show fullest usage of spell checking and thesaurus with TX Text Control we have started from the "TX Text Control Words" demo project distributed with TX Text Control. The following demonstrates nearly all requirements customers have faced. This article is aimed at TX Text Control 14 Professional (Pro is required for headers/footers/text-frames) - however it can easily be adapted for non Professional versions. Support for TX 14 was added in RapidSpell Desktop 3.8 and Thesaurus Desktop 1.1.0.
Downloads:
These projects show complete integration with both RapidSpell Desktop .NET and Thesaurus Desktop .NET, and therefore require both to be installed in order to run properly. If you prefer to only integrate RapidSpell, please see the RapidSpell only demo project included in the product trial/full download. C# Demo Project VB.NET Demo Project
1. RapidSpell Setup
a) Add references to Keyoti.RapidSpell.NET2.TXSupportv14.dll and Keyoti.RapidSpellMDict.dll
Starting from the "TX TextControl Words" the only things that need to be done are adding references in the project to Keyoti.RapidSpell.NET2.TXSupportv14.dll and Keyoti.RapidSpellMDict.dll (found in C:\Program Files\Keyoti Inc\RapidSpell Desktop .NET\3rd Party DLLs)
b) You may want to add controls from Keyoti.RapidSpell.NET2.TXSupportv14.dll to your tool box if not there already (right click toolbox, choose items, browse for Keyoti.RapidSpell.NET2.TXSupportv14.dll). Note, you must not have a reference to Keyoti.RapidSpell.dll or Keyoti.RapidSpell.NET2.dll in your project.
Note if you added items to your toolbox from the Keyoti.RapidSpell.NET2.dll, you will find that when dragging controls from the toolbox, that a reference is added to the Keyoti.RapidSpell.dll, this is OK, but remember to remove the reference from your project references
2. Adding RapidSpellAsYouType to TX Text Control
To begin with, as-you-type support will be added without concern for headers/footers/text-frames or context menus. In the "TX Text Control Words" demo project the TXTextControl.TextControl Control is located in the frmMain Form.
a) Drag the RapidSpellAsYouType control from the toolbox on to the Form frmMain.
b) Drag the TXTextControlAdapter control from the toolbox on to the form.
c) The simplest way to configure RapidSpellAsYouType in the designer's property editor is to first set TXTextControlAdapter.TextControl to the instance of TextControl, and then set RapidSpellAsYouType.TextComponent to the instance of TXTextControlAdapter. However, see the ContextMenu section for important points.
d) At this point the project can be run and the application will have as-you-type checking.
2.1 Working with existing ContextMenus / ContextMenuStrips
1. RapidSpellAsYouType will display it's own context menu when an error is underlined - to display other static menus when the click is not on an error, set the TXTextControlAdapter.ContextMenuDefault (or ContextMenuStripDefault) property to the desired ContextMenu(Strip).
2. The TextControl Words demo project shows a ContextMenuStrip on MouseDown events. To make this compatible with the spell checker, change the demo code from:
C#
private void textControl1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point pos = new Point(e.X, e.Y);
if (e.Button == MouseButtons.Right)ContextMenu_Text.Show(this, pos);
}
VB.NET
Private Sub textControl1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles textControl1.MouseDown
Dim pos As Point = New Point(e.X, e.Y)
If e.Button = Windows.Forms.MouseButtons.Right Then
ContextMenu_Text.Show(Me, pos)
End If
End Sub
to this, which gives the spell checker the choice of which ContextMenu to show.
C#
private void textControl1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) txTextControlAdapter1.ContextMenuStripDefault = ContextMenu_Text;
}
VB.NET
Private Sub textControl1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles textControl1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Right Then
txTextControlAdapter1.ContextMenuStripDefault = ContextMenu_Text
End If
End Sub
3. If you create context menus dynamically then you will need to approach this differently, please see the context menu section 2.3 Using A Dynamic ContextMenuStrip".
If your document can have headers, footers or text frames then you need to follow these instructions to implement correct spell checking.
1. Add this class to your project, which will handle the common tasks associated with headers, footers and text frames.
C#
using System;
using System.Collections;
using TXTextControl;
using Keyoti.RapidSpell;
using System.Windows.Forms;
namespace TX_Text_Control_Words
{
/// <summary>
/// TXHelper - glues TX and RapidSpell together.
/// </summary>
public class TXHelper
{
RapidSpellAsYouType ayt;
RapidSpellDialog dia;
TXTextControl.TextControl txc;
TXTextControlAdapter dialogAdapter;
TXTextControlAdapter[] adapters;
bool isTextFrameActive = false;
ContextMenuStrip defaultMenu;
public bool IsTextFrameActive { get { return isTextFrameActive; } }
/// <summary>
/// Configures the spell checkers to work with the text control, pass a null
/// spell checker object if not being used.
/// </summary>
public TXHelper(RapidSpellAsYouType ayt, RapidSpellDialog dia, TXTextControl.TextControl txc, ContextMenuStrip defaultMenu)
{
this.ayt = ayt;
this.dia = dia;
this.txc = txc;
this.defaultMenu = defaultMenu;
if (dia != null)
{
dialogAdapter = new TXTextControlAdapter(txc);
dialogAdapter.WorkWithCurrentlyActiveElementOnly = true;
dia.ThirdPartyTextComponentToCheck = dialogAdapter;
dia.SpellCheckStarted += new Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(dia_SpellCheckStarted);
dia.SpellCheckFinished += new Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(dia_SpellCheckFinished);
}
if (ayt != null)
{
this.txc.TextFrameCreated += new TextFrameEventHandler(txc_TextFrameCreated);
adapters = (TXTextControlAdapter[])getBasisAdapters().ToArray(typeof(TXTextControlAdapter));
this.ayt.UpdateAllTextBoxes = false;
this.ayt.TextComponents = adapters;
}
this.txc.TextFrameActivated += new TextFrameEventHandler(txc_TextFrameActivated);
this.txc.TextFrameDeactivated += new TextFrameEventHandler(txc_TextFrameDeactivated);
}
public void Dispose()
{
if (dia != null)
{
dia.SpellCheckStarted -= new Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(dia_SpellCheckStarted);
dia.SpellCheckFinished -= new Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(dia_SpellCheckFinished);
}
if (txc != null && !txc.IsDisposed)
{
this.txc.TextFrameCreated -= new TextFrameEventHandler(txc_TextFrameCreated);
this.txc.TextFrameActivated -= new TextFrameEventHandler(txc_TextFrameActivated);
this.txc.TextFrameDeactivated -= new TextFrameEventHandler(txc_TextFrameDeactivated);
}
}
ArrayList getBasisAdapters()
{
ArrayList adaps = new ArrayList();
TXTextControlAdapter adap;
//add main adapter
adap = new TXTextControlAdapter(this.txc);
adaps.Add(adap);
adap.ContextMenuStripDefault = defaultMenu;
//add adapters for headers/footers
if (txc.HeadersAndFooters != null)
{
foreach (HeaderFooter hf in this.txc.HeadersAndFooters)
{
adap = new TXTextControlAdapter(this.txc);
adap.HeaderFooter = hf;
adap.ContextMenuStripDefault = defaultMenu;
adaps.Add(adap);
}
}
return adaps;
}
private void dia_SpellCheckStarted(object sender, Keyoti.RapidSpell.Event.SpellCheckEventArgs e)
{
dialogAdapter.IgnoreHeaderFooterDeactivationEvents = true;
}
private void dia_SpellCheckFinished(object sender, Keyoti.RapidSpell.Event.SpellCheckEventArgs e)
{
dialogAdapter.IgnoreHeaderFooterDeactivationEvents = false;
}
//used for AYT only, this is only called when text frames come from the CLIPBOARD
private void txc_TextFrameCreated(object sender, TextFrameEventArgs e)
{
OnTextFrameCreated(e.TextFrame);
}
//used for AYT only
/// <summary>
/// Call when adding a TextFrame
/// </summary>
/// <param name="tf"></param>
public void OnTextFrameCreated(TextFrame tf)
{
TXTextControlAdapter adap = new TXTextControlAdapter(this.txc);
adap.TextFrame = tf;
adap.ContextMenuStripDefault = defaultMenu;
AddAdapter(adap);
}
void AddAdapter(TXTextControlAdapter newAdapter)
{
ArrayList basis = new ArrayList();
TXTextControlAdapter adap;
//refresh old adapters, note we must create new adapters as old ones are retired below
foreach (TXTextControlAdapter a in adapters)
{
adap = new TXTextControlAdapter(this.txc);
adap.SetWith(a);
adap.ContextMenuStripDefault = defaultMenu;
basis.Add(adap);
}
//add new adapter
basis.Add(newAdapter);
adapters = (TXTextControlAdapter[])basis.ToArray(typeof(TXTextControlAdapter));
//retire the old ones
ayt.TextComponents = null;
//add the new ones
ayt.TextComponents = adapters;
}
private void txc_TextFrameActivated(object sender, TextFrameEventArgs e)
{
isTextFrameActive = true;
}
private void txc_TextFrameDeactivated(object sender, TextFrameEventArgs e)
{
isTextFrameActive = false;
}
public void OnDocumentOpen()
{
ButtonBar bb = txc.ButtonBar;
RulerBar rb = txc.RulerBar;
RulerBar vrb = txc.VerticalRulerBar;
TXTextControl.StatusBar sb = txc.StatusBar;
txc.ButtonBar = null;
txc.RulerBar = null;
txc.VerticalRulerBar = null;
txc.StatusBar = null;
adapters[0].OnTextChanged(txc, EventArgs.Empty);
txc.ButtonBar = bb;
txc.RulerBar = rb;
txc.VerticalRulerBar = vrb;
txc.StatusBar = sb;
}
}
}
VB.NET
Imports System
Imports System.Collections
Imports TXTextControl
Imports Keyoti.RapidSpell
''' <summary>
''' TXHelper - glues TX and RapidSpell together.
''' </summary>
Public Class TXHelper
Private ayt As RapidSpellAsYouType
Private dia As RapidSpellDialog
Private WithEvents txc As TXTextControl.TextControl
Private dialogAdapter As TXTextControlAdapter
Private adapters() As TXTextControlAdapter
Private _isTextFrameActive = False
Private defaultMenu As ContextMenuStrip
Public ReadOnly Property IsTextFrameActive() As Boolean
Get
Return _isTextFrameActive
End Get
End Property
' Configures the spell checkers to work with the text control, pass a null
' spell checker object if not being used.
Public Sub New(ByRef ayt As RapidSpellAsYouType, ByRef dia As RapidSpellDialog, ByRef txc As TXTextControl.TextControl, ByRef defaultMenu As ContextMenuStrip)
Me.ayt = ayt
Me.dia = dia
Me.txc = txc
Me.defaultMenu = defaultMenu
If Not (dia Is Nothing) Then
dialogAdapter = New TXTextControlAdapter(txc)
dialogAdapter.WorkWithCurrentlyActiveElementOnly = True
Me.dia.ThirdPartyTextComponentToCheck = dialogAdapter
AddHandler dia.SpellCheckStarted, AddressOf dia_SpellCheckStarted
AddHandler dia.SpellCheckFinished, AddressOf dia_SpellCheckFinished
End If
If Not (ayt Is Nothing) Then
AddHandler Me.txc.TextFrameCreated, AddressOf txc_TextFrameCreated
adapters = CType(getBasisAdapters().ToArray(GetType(TXTextControlAdapter)), TXTextControlAdapter())
Me.ayt.UpdateAllTextBoxes = False
Me.ayt.TextComponents = adapters
End If
End Sub 'New
Public Sub Dispose()
If (Not dia Is Nothing) Then
RemoveHandler dia.SpellCheckStarted, New Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(AddressOf dia_SpellCheckStarted)
RemoveHandler dia.SpellCheckFinished, New Keyoti.RapidSpell.RapidSpellDialog.SpellCheckEventHandler(AddressOf dia_SpellCheckFinished)
End If
If (Not txc Is Nothing And Not txc.IsDisposed) Then
RemoveHandler txc.TextFrameCreated, New TextFrameEventHandler(AddressOf txc_TextFrameCreated)
RemoveHandler txc.TextFrameActivated, New TextFrameEventHandler(AddressOf txc_TextFrameActivated)
RemoveHandler txc.TextFrameDeactivated, New TextFrameEventHandler(AddressOf txc_TextFrameDeactivated)
End If
End Sub
Function getBasisAdapters() As ArrayList
Dim adaps As New ArrayList
Dim adap As TXTextControlAdapter
'add main adapter
adap = New TXTextControlAdapter(Me.txc)
adaps.Add(adap)
adap.ContextMenuStripDefault = defaultMenu
'add adapters for headers/footers
Dim hf As HeaderFooter
If (Not txc.HeadersAndFooters Is Nothing) Then
For Each hf In Me.txc.HeadersAndFooters
adap = New TXTextControlAdapter(Me.txc)
adap.HeaderFooter = hf
adap.ContextMenuStripDefault = defaultMenu
adaps.Add(adap)
Next hf
End If
Return adaps
End Function 'getBasisAdapters
Private Sub dia_SpellCheckStarted(ByVal sender As Object, ByVal e As Keyoti.RapidSpell.Event.SpellCheckEventArgs)
dialogAdapter.IgnoreHeaderFooterDeactivationEvents = True
End Sub 'dia_SpellCheckStarted
Private Sub dia_SpellCheckFinished(ByVal sender As Object, ByVal e As Keyoti.RapidSpell.Event.SpellCheckEventArgs)
dialogAdapter.IgnoreHeaderFooterDeactivationEvents = False
End Sub 'dia_SpellCheckFinished
'used for AYT only, this is only called when text frames come from the CLIPBOARD
Private Sub txc_TextFrameCreated(ByVal sender As Object, ByVal e As TextFrameEventArgs)
OnTextFrameCreated(e.TextFrame)
End Sub 'txc_TextFrameCreated
'used for AYT only
' Call when adding a TextFrame
Public Sub OnTextFrameCreated(ByVal tf As TextFrame)
Dim basis As New ArrayList
Dim adap As TXTextControlAdapter
'refresh old adapters, note we must create new adapters as old ones are retired below
Dim a As TXTextControlAdapter
For Each a In adapters
adap = New TXTextControlAdapter(Me.txc)
adap.SetWith(a)
basis.Add(adap)
Next a
'text frame adapter
adap = New TXTextControlAdapter(Me.txc)
adap.TextFrame = tf
basis.Add(adap)
adapters = CType(basis.ToArray(GetType(TXTextControlAdapter)), TXTextControlAdapter())
'retire the old ones
ayt.TextComponents = Nothing
'add the new ones
ayt.TextComponents = adapters
End Sub 'OnTextFrameCreated
Private Sub txc_TextFrameActivated(ByVal sender As Object, ByVal e As TXTextControl.TextFrameEventArgs) Handles txc.TextFrameActivated
Me._isTextFrameActive = True
End Sub
Private Sub txc_TextFrameDeactivated(ByVal sender As Object, ByVal e As TXTextControl.TextFrameEventArgs) Handles txc.TextFrameDeactivated
Me._isTextFrameActive = False
End Sub
Public Sub OnDocumentOpen()
Dim bb as ButtonBar = txc.ButtonBar
Dim rb as RulerBar = txc.RulerBar
Dim vrb as RulerBar = txc.VerticalRulerBar
Dim sb as TXTextControl.StatusBar = txc.StatusBar
txc.ButtonBar = Nothing
txc.RulerBar = Nothing
txc.VerticalRulerBar = Nothing
txc.StatusBar = Nothing
adapters(0).OnTextChanged(txc, EventArgs.Empty)
txc.ButtonBar = bb
txc.RulerBar = rb
txc.VerticalRulerBar = vrb
txc.StatusBar = sb
End Sub
End Class 'TXHelper
2. The TXHelper class creates it's own TXTextControlAdapter instances as needed, and does not use any added to the designer (as per instructions earlier in this article) - this means that a few changes need to be made
i) The TXTextControlAdapter added via the designer must now be deleted
ii) The code to switch the ContextMenu (textControl1_MouseDown and textControl1_TextFrameRightClicked) from section 2.1 can no longer be used and should be commented out
3. For the purposes of this article we will create a header in the load event of the form, and then add the TXHelper object.
C#//Declared in class
TXHelper helper;
....
#region " Form Events "
private void frmMain_Load(object sender, EventArgs e)
{
LoadAppSettings();
FileHandler1.TextControl = textControl1;
FileHandler1.RecentFilesMenuItem = recentFilesToolStripMenuItem;
//RapidSpell-
//create header/footer now
TXTextControl.HeaderFooterCollection hfc = this.textControl1.HeadersAndFooters;
hfc.Add(TXTextControl.HeaderFooterType.Header);
hfc.Add(TXTextControl.HeaderFooterType.Footer);
//the second argument should be RapidSpellDialog if it is being used aswell
helper = new TXHelper(rapidSpellAsYouType1, null, this.textControl1, ContextMenu_Text);
//-
if (m_LoadFileOnCreate)
{
if (!FileHandler1.FileOpen())
return;
if (FileHandler1.DocumentFileName != "")
this.Text = FileHandler1.DocumentFileName;
}
FileHandler1.DocumentDirty = false;
UpdateSaveStatus();
}
VB.NET
'Declared in class
Dim helper As TXHelper
....
#Region " Form Events "
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim commands As String = Microsoft.VisualBasic.Command()
LoadAppSettings()
FileHandler1.TextControl = textControl1
' Check if program has been started with a file name as a command line parameter
If commands = "" Then
FileNew()
Else
If commands.StartsWith("""") Then commands = commands.Replace("""", "")
If commands.EndsWith("""") Then commands = commands.Replace("""", "")
m_LoadFileOnCreate = True
FileHandler1.DocumentFileName = commands
End If
If m_LoadFileOnCreate Then
If Not FileHandler1.FileOpen Then
Return
End If
If Not (FileHandler1.DocumentFileName = "") Then
Me.Text = FileHandler1.DocumentFileName
End If
End If
Dim hfc As TXTextControl.HeaderFooterCollection
hfc = Me.textControl1.HeadersAndFooters
hfc.Add(TXTextControl.HeaderFooterType.Header)
hfc.Add(TXTextControl.HeaderFooterType.Footer)
'the second argument should be RapidSpellDialog if it is being used aswell
helper = New TXHelper(rapidSpellAsYouType1, Nothing, Me.textControl1, ContextMenu_Text)
FileHandler1.DocumentDirty = False
UpdateSaveStatus()
End Sub
We pass the RapidSpellAsYouType, the TextControl and also any default ContextMenuStrip we want to use (or null/Nothing if none).
At runtime, switch to page view and click near the top of the page to enter the header, you'll see if you type that spell checking is performed in the header/footer aswell.
4. The TXHelper class also takes care of TextFrame objects, however when adding text frames to the document, be sure to register the frame with TXHelper (call OnTextFrameCreated) - in this code we create the text frame in a menu item handler.
C# [Attach this handler to the menu item click event]
private void mnuInsert_TextFrame_Click(object sender, System.EventArgs e)
{
Size TextFrameSize = new Size(2000, 1000);
TXTextControl.TextFrame NewTextFrame = new TXTextControl.TextFrame(TextFrameSize);
textControl1.TextFrames.Add(NewTextFrame, TXTextControl.HorizontalAlignment.Left, -1, TXTextControl.TextFrameInsertionMode.DisplaceText);
//Must inform helper of this
helper.OnTextFrameCreated(NewTextFrame);
}
VB.NET
Private Sub mnuInsert_TextFrame_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuInsert_TextFrame.Click
Dim TextFrameSize As Size = New Size(2000, 1000)
Dim NewTextFrame As TXTextControl.TextFrame = New TXTextControl.TextFrame(TextFrameSize)
textControl1.TextFrames.Add(NewTextFrame, TXTextControl.HorizontalAlignment.Left, -1, TXTextControl.TextFrameInsertionMode.DisplaceText)
'Must inform helper of this
helper.OnTextFrameCreated(NewTextFrame)
End Sub
5. The final touch is to inform the helper object when a document is loaded, this informs the spell checker that the document has changed.
C#
public void FileOpen()
{
...
helper.OnDocumentOpen();
}
VB.NET
Public Sub FileOpen()
...
helper.OnDocumentOpen()
End Sub
Creating ContextMenuStrip with suggestions dynamically.
1. Previously the helper object was passed an instance of the default context menu, this should now be null/Nothing as we don't wish to use a default, static menu.
C#
helper = new TXHelper(rapidSpellAsYouType1, rapidSpellDialog1, this.textControl1, null);
VB.NET
helper = New TXHelper(rapidSpellAsYouType1, Nothing, Me.textControl1, Nothing)
2. An empty ContextMenuStrip is added to the form and set as the ContextMenuStrip for the TextControl - and the ContextMenuStrip is given one dummy item (necessary otherwise strip won't be shown first time).
3. RapidSpellAsYouType.ShowSuggestionsContextMenu is set to false.
4. The ContextMenuStrip.Opening event is subscribed to and the handler will generate the ToolStripItems as needed.
C# [Attach this event handler to the menu opening event]
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
//clear any old suggestions
contextMenuStrip1.Items.Clear();
ToolStripItem[] suggs = rapidSpellAsYouType1.GetSuggestionsToolStripItems();
//Add our regular items
contextMenuStrip1.Items.Add("Item 1");
contextMenuStrip1.Items.Add("Item 2");
//If we have suggestions, add them too
if (suggs != null)
{
contextMenuStrip1.Items.Add(new ToolStripSeparator());
contextMenuStrip1.Items.AddRange(suggs);
}
}
VB.NET
Private Sub contextMenuStrip1_Opening(ByVal sender As Object, ByVal e As CancelEventArgs) _
Handles contextMenuStrip1.Opening
'clear any old suggestions
contextMenuStrip1.Items.Clear
Dim suggs() As ToolStripItem = rapidSpellAsYouType1.GetSuggestionsToolStripItems
'Add our regular items
contextMenuStrip1.Items.Add("Item 1")
contextMenuStrip1.Items.Add("Item 2")
'If we have suggestions, add them too
If (Not (suggs) Is Nothing) Then
contextMenuStrip1.Items.Add(New ToolStripSeparator)
contextMenuStrip1.Items.AddRange(suggs)
End If
End Sub
Two things to do when loading and saving documents.
1. When loading, call TXHelper.OnDocumentOpen or (if not using TXHelper) TXTextControlAdapter.DocumentLoaded. This ensures RapidSpell knows that the document has changed.
2. When saving, remove underlines and stop spell checking by calling rapidSpellAsYouType1.CheckAsYouType = false. This removes underlines from the document, which are actually part of the document, and prevents them being saved with the document. After saving it is OK to call rapidSpellAsYouType1.CheckAsYouType = true
3. When loading/closing a document the toolbar/rulers may flash (if not using TXHelper), to prevent this, temporarily deactivate them by setting the associated properties in TextControl to null/Nothing and then back to the real values after the operation is complete (see OnDocumentOpen in TXHelper for an example).
3. Adding RapidSpellDialog to TX Text Control
There are two ways to do this, the first way below is if you are not working with headers/footers or text-frames, the second way continues on from the as-you-type integration instructions above.
2. Drag a TXTextControlAdapter control onto the form.
3. In the property editor set TXTextControlAdapter.TextControl to the instance of TextControl, and then to set RapidSpellDialog.ThirdPartyTextComponentToCheck to the instance of TXTextControlAdapter. Note if you do not see any options in the property editor drop down, please close the designer and reopen it - sometimes Visual Studio fails to correctly identify possible objects.
4. Add a menu item and an event handler to start the dialog spell check.
C# [Attach this event handler to the menu item click event]
private void SpellCheck_menuItem7_Click(object sender, System.EventArgs e)
{
this.rapidSpellDialog1.Check();
}
VB.NET
Private Sub SpellCheck_MenuItem19_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SpellCheck_MenuItem19.Click
Me.RapidSpellDialog1.Check()
End Sub
3.2 Full, integration with headers/footers and text frames
Please note that due to technical limitations it is only possible for the dialog checker to check the currently active element, e.g. header/footer/text-frame/body.
Continuing on from the as-you-type instructions.
1. Drag a RapidSpellDialog control onto the form.
2. Referring to section 2.2, the TXHelper is now constructed with the RapidSpellDialog instance.
C#//Declared in class
TXHelper helper;
....
#region " Form Events "
private void frmMain_Load(object sender, EventArgs e)
{
LoadAppSettings();
FileHandler1.TextControl = textControl1;
FileHandler1.RecentFilesMenuItem = recentFilesToolStripMenuItem;
//RapidSpell-
//create header/footer now
TXTextControl.HeaderFooterCollection hfc = this.textControl1.HeadersAndFooters;
hfc.Add(TXTextControl.HeaderFooterType.Header);
hfc.Add(TXTextControl.HeaderFooterType.Footer);
//the second argument should be RapidSpellDialog if it is being used aswell
helper = new TXHelper(rapidSpellAsYouType1, rapidSpellDialog1, this.textControl1, ContextMenu_Text);
//-
if (m_LoadFileOnCreate)
{
if (!FileHandler1.FileOpen())
return;
if (FileHandler1.DocumentFileName != "")
this.Text = FileHandler1.DocumentFileName;
}
FileHandler1.DocumentDirty = false;
UpdateSaveStatus();
}
VB.NET
'Declared in class
Dim helper As TXHelper
....
#Region " Form Events "
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim commands As String = Microsoft.VisualBasic.Command()
LoadAppSettings()
FileHandler1.TextControl = textControl1
' Check if program has been started with a file name as a command line parameter
If commands = "" Then
FileNew()
Else
If commands.StartsWith("""") Then commands = commands.Replace("""", "")
If commands.EndsWith("""") Then commands = commands.Replace("""", "")
m_LoadFileOnCreate = True
FileHandler1.DocumentFileName = commands
End If
If m_LoadFileOnCreate Then
If Not FileHandler1.FileOpen Then
Return
End If
If Not (FileHandler1.DocumentFileName = "") Then
Me.Text = FileHandler1.DocumentFileName
End If
End If
Dim hfc As TXTextControl.HeaderFooterCollection
hfc = Me.textControl1.HeadersAndFooters
hfc.Add(TXTextControl.HeaderFooterType.Header)
hfc.Add(TXTextControl.HeaderFooterType.Footer)
'the second argument should be RapidSpellDialog if it is being used aswell
helper = New TXHelper(rapidSpellAsYouType1, rapidSpellDialog1, Me.textControl1, ContextMenu_Text)
FileHandler1.DocumentDirty = False
UpdateSaveStatus()
End Sub
4. Add a menu item and an event handler to start the dialog spell check.
C# [Attach this event handler to the menu item click event]
private void sToolStripMenuItem_Click(object sender, EventArgs e)
{
rapidSpellDialog1.Check();
}
VB.NET
Private Sub SpellCheck_MenuItem19_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SpellCheck_MenuItem19.Click
Me.RapidSpellDialog1.Check()
End Sub
5. This is enough to get both spell checkers working independently however it's usually desirable to have dialog and as-you-type working in unison, so that words which are "ignore all'ed" in one, are ignored in the other. To do this, drag the RapidSpellAYTDialogCoupler control onto the form and set it's RapidSpellAsYouType and RapidSpellDialog properties to the existing controls of the same name on the form (note if you do not see them as options in the property editor, please close and reopen the designer window - as Visual Studio sometimes fails to pick up objects as options).
a) Add references to Keyoti.Thesaurus.TXTextControlAdapter.v14.dll and Keyoti.Thesaurus.Windows.NET2.DLL (found under C:\Program Files\Keyoti Inc\Thesaurus Desktop .NET)
b) You may want to add controls from both DLLs to your tool box (right click toolbox, add/remove items, find controls named Thesaurus, Thesaurus Control and ThesaurusTXAdapter). Note, be sure to select the TX adapter control for the correct version; You will see multiple controls in the list, for different TX versions, ensure you pick the TX14 version, otherwise you will get references added to your project which are dependent on a different TX version.
2. Drag the ThesaurusTXAdapter control onto the form.
3. Set ThesaurusTXAdapter.Control to the instance of TextControl, and set Thesaurus.ThirdPartyTextComponent to the instance of ThesaurusTXAdapter.
4. Add a menu item for the Thesaurus in the main menu and an event handler to start the Thesaurus dialog.
C# [Attach this event handler to the menu item click event]
private void thesaurusToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.textControl1.Text.Length == 0)
MessageBox.Show("You must select a word to use the thesaurus.");
else
{
this.thesaurus1.DialogForm.TopMost = true;
this.thesaurus1.Show();
}
}
VB.NET
Private Sub ThesaurusToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ThesaurusToolStripMenuItem.Click
If Me.textControl1.Text.Length = 0 Then
MessageBox.Show("You must select a word to use the thesaurus.")
Else
Thesaurus1.DialogForm.TopMost = True
Me.Thesaurus1.Show()
End If
End Sub
Continuing on from section 3.2, we will now modify the as-you-type context menu and integrate with a new dynamic menu.
1. Follow all steps in 5.1 to add the dialog thesaurus.
2. The nature of the thesaurus is such that it's context menu is suited to being a sub-menu, so it is necessary to build the ContextMenu items at run-time. Add a context menu to the form if one doesn't already exist and assign it to the TextControl instance (the demo project will use the existing ContextMenu_Text menu).
3. Add a menu item called "Synonyms" to the context menu strip, this is where the thesaurus items will be added.
4. Handle the context menu strip's Opening event, and create the menu items there. (The demo project uses ContextMenu_Text which already has an Opening handler).
C# [Attach this event handler to the menu PopUp event]
private void ContextMenu_Text_Popup(object sender, System.EventArgs e)
{
ContextMenu_Text_TableProperties.Enabled = (textControl1.Tables.GetItem() != null);
ContextMenu_Text_Cut.Enabled = textControl1.CanCopy;
ContextMenu_Text_Copy.Enabled = textControl1.CanCopy;
ContextMenu_Text_Paste.Enabled = textControl1.CanPaste;
ToolStripItem[] suggs = thesaurus1.GetSuggestionToolStripItems();
synonymsToolStripMenuItem.DropDown.Items.Clear();
//If we have suggestions, add them too
if (suggs != null)
{
synonymsToolStripMenuItem.DropDown.Items.AddRange(suggs);
}
else
{
ToolStripMenuItem noSuggs = new ToolStripMenuItem("No suggestions");
noSuggs.Enabled = false;
synonymsToolStripMenuItem.DropDown.Items.Add(noSuggs);
}
}
VB.NET
Private Sub ContextMenu_Text_Popup(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ContextMenu_Text.Opening
ContextMenu_Text_TableProperties.Enabled = (Not (textControl1.Tables.GetItem Is Nothing))
ContextMenu_Text_Cut.Enabled = textControl1.CanCopy
ContextMenu_Text_Copy.Enabled = textControl1.CanCopy
ContextMenu_Text_Paste.Enabled = textControl1.CanPaste
Dim suggs As ToolStripItem() = Thesaurus1.GetSuggestionToolStripItems()
synonymsToolStripMenuItem.DropDown.Items.Clear()
'If we have suggestions, add them too
If (Not suggs Is Nothing) Then
synonymsToolStripMenuItem.DropDown.Items.AddRange(suggs)
Else
Dim noSuggs As New ToolStripMenuItem("No suggestions")
noSuggs.Enabled = False
synonymsToolStripMenuItem.DropDown.Items.Add(noSuggs)
End If
End Sub
Conclusion
We hope that this article has shed light on how to achieve more advanced integration requirements. If you have questions or problems please feel free to email support@keyoti.com for assistance.
Downloads:
These projects show complete integration with both RapidSpell Desktop .NET and Thesaurus Desktop .NET, and therefore require both to be installed in order to run properly.