Advanced spelling correction user interface

Compared to SpellingCorrectionUIProvider Simple, four new features are added to the SpellingCorrectionUIProvider Advanced sample project:

The source code is contained in the following directories:

Correcting all matches of the current misspelled word by using the ChangeAll, IgnoreAll and AddToDicionary methods:

There are three new buttons to correct the current misspelled word and all its occurrences: The 'Change All', 'Ignore All' and 'Add To Dict.' button. As previously described in Simple spelling correction user interface, the Enabled states of these Buttons are also bound inside the Form_Load event and the corresponding methods are handled by the Button's Clicked events.

Relevant API links:

[C#]
private void Form1_Load(object sender, EventArgs e)
{
	...
	buttonChangeAll.DataBindings.Add(new Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsChangeAllEnabled"));
	buttonIgnoreAll.DataBindings.Add(new Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsIgnoreAllEnabled"));
	buttonAddToDict.DataBindings.Add(new Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsAddToDictionaryEnabled"));
}

private void buttonChangeAll_Click(object sender, EventArgs e)
{
	...
	// change the current misspelled word and all accordances with the suggestion selected in the ListBox
	txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.ChangeAll(listBoxSuggestions.Text);
	...
}

private void buttonIgnoreAll_Click(object sender, EventArgs e)
{
	// ignore the current misspelled word and all accordances
	txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.IgnoreAll();
}

private void buttonAddToDict_Click(object sender, EventArgs e)
{
	// add the current misspelled word to a user dictionary
	txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.AddToDictionary();
}
[Visual Basic]
Private Sub Form1_Load(sender As Object, e As EventArgs)
	...
	' connect the TextControl to the TX Spell correction user interface manager
	buttonChangeAll.DataBindings.Add(New Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsChangeAllEnabled"))
	buttonIgnoreAll.DataBindings.Add(New Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsIgnoreAllEnabled"))
	buttonAddToDict.DataBindings.Add(New Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsAddToDictionaryEnabled"))
End Sub

Private Sub buttonChangeAll_Click(sender As Object, e As EventArgs)
	...
	' change the current misspelled word and all accordances with the suggestion selected in the ListBox
	txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.ChangeAll(listBoxSuggestions.Text)
	...
End Sub

Private Sub buttonIgnoreAll_Click(sender As Object, e As EventArgs)
	 ' ignore the current misspelled word and all accordances
	txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.IgnoreAll()
End Sub

Private Sub buttonAddToDict_Click(sender As Object, e As EventArgs)
	' add the current misspelled word to a user dictionary
	 txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.AddToDictionary()
End Sub

Selecting a dictionary to create suggestions:

In some cases, it is necessary to use more than one dictionary to correct a text. To provide suggestions of one or more specific dictionaries, the user can set the corresponding dictionaries by using the properties of the SuggestionDictionariesHandler class. The recommended way to handle these kind of operations is first getting those dictionaries where the language matches the language of the current misspelled word by calling the SuggestionDictionariesHandler.SuggestionDictionaries property and then adding one or more of these dictionaries to the SuggestionDictionariesHandler.SelectedSuggestionDictionaries property. If this operation causes the creation of new suggestions and the SuggestionsHandler.Suggestions property is bound to a ListBox (see Simple spelling correction user interface), the property and the suggestion ListBox are updated automatically.

In this example, the available suggestion dictionaries are provided by a ComboBox where the DataSource property is bound to the SuggestionDictionariesHandler.SuggestionDictionaries property. Additionally, the ComboBox's Enabled state is bound to the SuggestionDictionariesHandler.IsSuggestionDictionariesEnabled property. If the user changes the selected suggestion dictionary, the corresponding SelectedIndexChanged event adds the new dictionary to the SuggestionDictionariesHandler.SelectedSuggestionDictionaries property.

Relevant API links:

[C#]
private void Form1_Load(object sender, EventArgs e)
{
	...
	// adding data bindings to set the enabled state and automatically add the misspelled words's language depending suggestion dictionaries to the combo box
	comboBoxSuggestionDictionaries.DataBindings.Add(new Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling, "IsSuggestionDictionariesEnabled"));
	comboBoxSuggestionDictionaries.DataBindings.Add(new Binding("DataSource", txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling, "SuggestionDictionaries"));
}

private void comboBoxSuggestionDictionaries_SelectedIndexChanged(object sender, EventArgs e)
{
	// Sets the current suggestion dictionaries combo box's selected dictionary as selected dictionary to use for creating suggestions
	txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling.SelectedSuggestionDictionaries = new TXTextControl.Proofing.Dictionary[] { (TXTextControl.Proofing.Dictionary)comboBoxSuggestionDictionaries.SelectedItem };
}
[Visual Basic]
Private Sub Form1_Load(sender As Object, e As EventArgs)
	...
	' adding data bindings to set the enabled state and automatically add the misspelled words's language depending suggestion dictionaries to the combo box
	comboBoxSuggestionDictionaries.DataBindings.Add(New Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling, "IsSuggestionDictionariesEnabled"))
	comboBoxSuggestionDictionaries.DataBindings.Add(New Binding("DataSource", txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling, "SuggestionDictionaries"))
End Sub

Private Sub comboBoxSuggestionDictionaries_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles comboBoxSuggestionDictionaries.SelectedIndexChanged
	' Sets the current suggestion dictionaries combo box's selected dictionary as selected dictionary to use for creating suggestions
	txSpellChecker1.SpellingCorrectionUIProvider.SuggestionDictionariesHandling.SelectedSuggestionDictionaries = New TXTextControl.Proofing.Dictionary() {DirectCast(comboBoxSuggestionDictionaries.SelectedItem, TXTextControl.Proofing.Dictionary)}
End Sub

Displaying the sentence where the misspelled word is located:

Determining the sentence where the current misspelled word is located could be helpful to correct the word depending on its surrounding. For these cases the PreviewHandler.PreviewSentenceBounds property provides the index and the length of the misspelled word's sentence.

Applied to our example, the sentence extraction is handled by the Format event of the Binding object which connects a RichtTextBox.Text property with the PreviewHandler.PreviewSentenceBounds property. Consequently, on every PreviewSentenceBounds property change, the Format event is raised where finally the misspelled word's sentence text is determined and commited to the RichtTextBox.Text property.

Relevant API links:

[C#]
private void Form1_Load(object sender, EventArgs e)
{
	...
	// adding data binding for the richt text box to get the current misspelled word's sentence.
	Binding sentenceBinding = new Binding("Text", txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling, "PreviewSentenceBounds");
	sentenceBinding.Format += new ConvertEventHandler(sentenceBinding_Format);
	richTextBoxSentence.DataBindings.Add(sentenceBinding);
}

private void sentenceBinding_Format(object sender, ConvertEventArgs e)
{
	if (txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling.PreviewSentenceBounds != null)
	{
		e.Value = GetMisspelledWordSentence();
	}
	else
	{
		e.Value = "";
	}
}

private string GetMisspelledWordSentence()
{
	TXTextControl.IFormattedText iftCurrentTextPart = (TXTextControl.IFormattedText)txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentIFormattedText;
	TXTextControl.Paragraph pgMisspelledWordsParagraph = iftCurrentTextPart.Paragraphs.GetItem(((TXTextControl.MisspelledWord)txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect).Start);
	int[] riPreviewSentenceBounds = txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling.PreviewSentenceBounds;
	return pgMisspelledWordsParagraph.Text.Substring(riPreviewSentenceBounds[0] - (pgMisspelledWordsParagraph.Start - 1), riPreviewSentenceBounds[1]);
}
[Visual Basic]
Private Sub Form1_Load(sender As Object, e As EventArgs)
	...
	' adding data binding for the richt text box to get the current misspelled word's sentence.
	Dim sentenceBinding As New Binding("Text", txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling, "PreviewSentenceBounds")
	AddHandler sentenceBinding.Format, New ConvertEventHandler(AddressOf sentenceBinding_Format)
	richTextBoxSentence.DataBindings.Add(sentenceBinding)
End Sub

Private Sub sentenceBinding_Format(ByVal sender As Object, ByVal e As ConvertEventArgs)
	If txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling.PreviewSentenceBounds IsNot Nothing Then
		 e.Value = GetMisspelledWordSentence()
	Else
		e.Value = ""
	End If
End Sub

Private Function GetMisspelledWordSentence() As String
	Dim iftCurrentTextPart As TXTextControl.IFormattedText = DirectCast(txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentIFormattedText, TXTextControl.IFormattedText)
	TXTextControl.Paragraph pgMisspelledWordsParagraph = iftCurrentTextPart.Paragraphs.GetItem(((TXTextControl.MisspelledWord)txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect).Start);
	Dim pgMisspelledWordsParagraph As TXTextControl.Paragraph = iftCurrentTextPart.Paragraphs.GetItem(DirectCast(txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect, TXTextControl.MisspelledWord).Start)
	Dim riPreviewSentenceBounds As Integer() = txSpellChecker1.SpellingCorrectionUIProvider.PreviewHandling.PreviewSentenceBounds
	Return pgMisspelledWordsParagraph.Text.Substring(riPreviewSentenceBounds(0) - (pgMisspelledWordsParagraph.Start - 1), riPreviewSentenceBounds(1))
End Sub

Setting a suggestion manually to correct the current misspelled word:

Sometimes, no suggestions can be created for a misspelled word. In this case, the user needs an interface to correct the word manually.

The SpellingCorrectionUIProvider Advanced sample project provides a TextBox to give the user the opportunity to edit the current misspelled word which is updated inside the box on every StateManager.CurrentWordToCorrect property change. The edited word is applied when the user clicks the 'Change' or 'Change All' button.

Relevant API links:

[C#]
private void Form1_Load(object sender, EventArgs e)
{
	...
	// adding data binding for the text box to get the current misspelled word.
	Binding misspelledWordBinding = new Binding("Text", txSpellChecker1.SpellingCorrectionUIProvider.StateManaging, "CurrentWordToCorrect", true, DataSourceUpdateMode.Never);
	misspelledWordBinding.Format += new ConvertEventHandler(misspelledWordBinding_Format);
	textBoxEdit.DataBindings.Add(misspelledWordBinding);
}

private void misspelledWordBinding_Format(object sender, ConvertEventArgs e)
{
	if (txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect != null)
	{
		e.Value = ((TXTextControl.MisspelledWord)txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect).Text;
		...
	}
	else
	{
		e.Value = "";
		...
	}
}
private void buttonChange_Click(object sender, EventArgs e)
{
	if (txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing) {
	{
		// change the current misspelled word with the text box's text.
		txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.Change(textBoxEdit.Text);
	}
	else
	{
		// change the current misspelled word with the suggestion selected in the ListBox
		txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.Change(listBoxSuggestions.Text);
	}
}
[Visual Basic]
Private Sub Form1_Load(sender As Object, e As EventArgs)
	...
	' adding data binding for the text box to get the current misspelled word.
	Dim misspelledWordBinding As New Binding("Text", txSpellChecker1.SpellingCorrectionUIProvider.StateManaging, "CurrentWordToCorrect", True, DataSourceUpdateMode.Never)
	AddHandler misspelledWordBinding.Format, New ConvertEventHandler(AddressOf misspelledWordBinding_Format)
	textBoxEdit.DataBindings.Add(misspelledWordBinding)
End Sub

Private Sub misspelledWordBinding_Format(ByVal sender As Object, ByVal e As ConvertEventArgs)
	If txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect IsNot Nothing Then
		 e.Value = DirectCast(txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect, TXTextControl.MisspelledWord).Text
		...
	Else
		e.Value = ""
		...
	End If
End Sub

Private Sub buttonChange_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonChange.Click
	If txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing Then
		' change the current misspelled word with the text box's text.
		txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.Change(textBoxEdit.Text)
	Else
		' change the current misspelled word with the suggestion selected in the ListBox
		txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.Change(listBoxSuggestions.Text)
	End If
End Sub

Additionally, the TextBox's TextChanged event calls the CorrectionHandler.CheckCorrectedWord method to check whether the edited TextBox' text is correct or not.

Relevant API links:

[C#]
private void textBoxEdit_TextChanged(object sender, EventArgs e) 
{
	if (txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.Mode != TXTextControl.Proofing.TXSpell.SpellingCorrectionMode.CorrectionCompleted)
	{
		string message;
		if (txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.CheckCorrectedWord(textBoxEdit.Text, out message))
		{
			// ... do something to show that the text box's text is correct
		}
		else
		{
			// ... do something to show that the text box's text is still incorrect
		}
	}
	else
	{
		// ... the spelling correction is completed. There is no text to check for correctness
	}
}
[Visual Basic]
Private Sub textBoxEdit_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles textBoxEdit.TextChanged
	If txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.Mode <> TXTextControl.Proofing.TXSpell.SpellingCorrectionMode.CorrectionCompleted Then
		Dim message As String = String.Empty
		If txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling.CheckCorrectedWord(textBoxEdit.Text, message) Then
			' ... do something to show that the text box's text is correct
		Else
			' ... do something to show that the text box's text is still incorrect
		End If
	Else
		' ... the spelling correction is completed. There is no text to check for correctness
	End If
End Sub

To inform the SpellingCorrectionUIProvider that the user is currently editing the word manually, the StateManager.IsWordToCorrectEditing property is set to true on the first editing operation. To leave the editing mode, the user can press the 'Undo Edit' button where the Proofing.SpellingCorrectionUIProvider.StateManager.IsWordToCorrectEditing property is set to false.

Relevant API links:

[C#]
private void Form1_Load(object sender, EventArgs e)
{
	...
	buttonUndoEdit.DataBindings.Add(new Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsUndoEditEnabled"));
}

private void textBoxEdit_KeyDown(object sender, KeyEventArgs e)
{
	// start word editing
	txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing = true;
}

private void buttonUndoEdit_Click(object sender, EventArgs e)
{
	// abort word editing
	txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing = false;
	textBoxEdit.Text = ((TXTextControl.MisspelledWord)txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect).Text;
	buttonIgnore.Focus();
}
[Visual Basic]
Private Sub Form1_Load(sender As Object, e As EventArgs)
	...
	buttonUndoEdit.DataBindings.Add(New Binding("Enabled", txSpellChecker1.SpellingCorrectionUIProvider.CorrectionHandling, "IsUndoEditEnabled"))
End Sub

Private Sub textBoxEdit_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles textBoxEdit.KeyDown
	' start word editing
	txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing = True
End Sub

Private Sub buttonUndoEdit_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonUndoEdit.Click
	' abort word editing
	txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.IsWordToCorrectEditing = False
	textBoxEdit.Text = DirectCast(txSpellChecker1.SpellingCorrectionUIProvider.StateManaging.CurrentWordToCorrect, TXTextControl.MisspelledWord).Text
	buttonIgnore.Focus()
End Sub