Introducing DotNetFunda.com on mobile http://m.dotnetfunda.com ! Be with DotNetFunda.com on the go !
Go to DotNetFunda.com
Twitter TwitterLinkedIn
YouTubeGoogle
 Online : 5728 |  Welcome, Guest!   Register  Login
Home > Articles > WPF > SpellChecker in WPF

SpellChecker in WPF

6 vote(s)
Rating: 3.67 out of 5
Article posted by Abhi2434 on 4/11/2010 | Views: 11115 | Category: WPF | Level: Beginner red flag


WPF has an inbuilt feature of Spellchecking. In this article I have explored the SpellCheck functionality of WPF TextBoxBase object.

CustomDictionaries introduced with WPF 4.0 is also discussed with this article

Download


 Download source code for SpellChecker in WPF


Introduction


WPF comes with an inbuilt feature of SpellCheck. SpellCheck is added to TextBoxBase object, which inherits all the textual input controls automatically. Thus any input control will automatically derive the Spell Checking functionality.

In this article I would like to introduce how you can explore this feature to your own application.


Basic Usage


WPF provides a new object called SpellCheck. This object can be applied to any TextBoxBase object and thereby the object will behave automatically with the spellcheck functionality. To do this, lets look at the example :

<StackPanel Height="150" Margin="50">
<TextBlock Text="Enter Content" ></TextBlock>
<TextBox x:Name="txtBox" SpellCheck.IsEnabled="True" AcceptsReturn="True" />
</StackPanel>
In the above example, you can see the TextBox txtBox, have SpellChecker enabled. This ensures the textbox automatically detect misspelled words and will put an underline on the word. When you run the application, you will see the textbox to appear like this :



You can see all the misspelled word is shown with red underline. These words can easily be corrected by using the TextBox default ContextMenu. Right clicking on the word will give you a list of suggestions for the current word which you might choose to change the word in the paragraph.

SpellCheck.IsEnabled is actually a Dependency property. So you can easily use it to set in Style setters. You can also use global setter to apply SpellChecking to every control you put in the window very easily.

<Style TargetType="{x:Type TextBoxBase}" x:Key="txtBasic" >
<Setter Property="SpellCheck.IsEnabled" Value="true" />
<Setter Property="SpellCheck.SpellingReform" Value="PreAndPostreform" />
</Style>

Now you can easily define any TextBox or RichTextBox or any control that derives TextboxBase and use the Style to apply SpellChecker. You can also use

<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource txtBasic}" />
<Style TargetType="{x:Type RichTextBox}" BasedOn="{StaticResource txtBasic}" />

By doing this, any TextBox or RichTextBox which you place in your Window will automatically have spellChecking enabled.

You can also enable/disable the SpellCheck from codebehind.

SpellCheck.SetIsEnabled(txtBox, true);
SpellCheck.SetSpellingReform(txtBox, SpellingReform.PreAndPostreform);

Spelling error can be detected based on the carat location. TextBoxBase contains a few methods that you can invoke to get Spelling errors. SpellingError is a class which provides the current Spelling error word with an enumerable of Suggessions.

Lets say you want to display the suggessions into your own Listbox.

<TextBlock Text="Enter Content"  ></TextBlock>
<TextBox x:Name="txtBox" AcceptsReturn="True" Keyboard.KeyUp="txtBox_KeyUp"/>
<TextBlock Text="Suggessions" ></TextBlock>
<ListBox x:Name="lstSuggessions" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Thus you can see, I have declared a ListBox which will show you the Suggessions that are populated in the contextmenu. To do this you can write like this :

private void txtBox_KeyUp(object sender, KeyEventArgs e)
{
int catatPos = txtBox.CaretIndex;
lstSuggessions.Items.Clear();
SpellingError error = txtBox.GetSpellingError(catatPos);
if (error != null)
{
foreach (string suggession in error.Suggestions)
lstSuggessions.Items.Add(suggession);
}
}

Here we are using SpellingError class to get the Suggessions. CaretIndex returns the index where the carat is in the textbox. GetSpellingError can return SpellingError object only when the current Carat location has a word with errors and also SpellCheck is enabled for the TextBox. 


You can use EditingCommands.CorrectSpellingError to correct the spelling.

Building ContextMenu


It is true that the default contextmenu cannot be styled. You need to redefine the contextMenu again to have it styled. Let us look how you can redefine the ContextMenu yourself.

private void txtBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
ContextMenu menu = this.Resources["ctxMenu"] as ContextMenu;
this.ClearSpellCheckMenuItems(menu);
int catatPos = txtBox.CaretIndex;
SpellingError error = txtBox.GetSpellingError(catatPos);
if (error != null)
{
this.txtBox.ContextMenu.Items.Insert(0, new Separator());
MenuItem item = this.GetMenu("Ignore All", EditingCommands.IgnoreSpellingError, this.txtBox);
item.Tag = "S";
this.txtBox.ContextMenu.Items.Insert(0, item);
foreach (string suggession in error.Suggestions)
{
item = this.GetMenu(suggession, EditingCommands.CorrectSpellingError, this.txtBox);
item.Tag = "S";
this.txtBox.ContextMenu.Items.Insert(0, item);
}

}
}
private MenuItem GetMenu(string header, ICommand command, TextBoxBase target)
{
MenuItem item = new MenuItem();
item.Header = header;
item.Command = command;
item.CommandParameter = header;
item.CommandTarget = target;
return item;
}
private void ClearSpellCheckMenuItems(ContextMenu menu)
{
for (int i = 0; i < menu.Items.Count; i++)
{
MenuItem item = menu.Items[i] as MenuItem;
if (item != null && item.Tag != null)
menu.Items.RemoveAt(i);
}
}
Here I have built the contextmenu dynamically. The EditingCommand.CorrectSpellingError will take a string parameter which I have passed from Suggession and the target as the control. The GetMenu will build every menuItem. IgnoreAll can also be created using EditingCommand.IgnoreSpellingError.

It is to be noted that I have added each menuitem from the beginning. It is because each item is added at 0th index so that each new item will come above the other.  It is preferable to use the reverse always.

Limitation of SpellCheck


SpellCheck of WPF has few basic Limitations.

  1. SpellChecking functionality is restricted to English, Spanish, French and German.
  2. You cannot create CustomDictionaries for Textboxes. So if you want to ignore a specific word, it will be ignored once only for the current application run. If you rerun the application, you need to ignore the same word again.

CustomDictionaries with WPF 4.0


With the introduction of WPF 4.0, SpellCheck object is somehow modified to support CustomDictionaries. This is really a good addition to WPF Spell Checker. Let us look how you can use it:

<TextBox x:Name="txtCustom" SpellCheck.IsEnabled="True">
<SpellCheck.CustomDictionaries>
<sys:Uri>location\dictionary.lex</sys:Uri>
</SpellCheck.CustomDictionaries>
</TextBox>
In the above Code you can see I have added custom dictionaries to the TextBox. sys points to System in System.dll(xmlns:sys="clr-namespace:System;assembly=System"). CustomDictionaries is a collection of all dictionaries which you can add to your textbox control so that when text is entered into the textbox it will ignore if misspelled but exists in the CustomDictionary file.

CustomDictionary file is actually a Text file which have every words placed in new lines. While loading the textbox, WPF reads the entire file into context and recreates its dictionary dynamically.

You can also create a custom "Add to Dictionary" to add the current item into dictionary. To do this,

MenuItem item = new MenuItem();
item.Header = "Add to Dictionary";
item.Click += new RoutedEventHandler(AddDict_Click);
item.Command = EditingCommands.IgnoreSpellingError;
item.CommandParameter = currentText;
item.CommandTarget = txtBox;
So now the AddDict_Click will be called automatically when we select the Add To Dictionary object. You can see I have also used item.Command as EditingCommands.IgnoreSpellingError, which will ignore the word to current textbox. Thus you only need to write the logic to open the Dictionary file and write the element in CommandParameter to the file. 

Conclusion


SpellCheck is a great option to WPF. You can easily use it to build a better solution for your client. I hope this article will help you to a great extent. Please feel free to write your feedback.

If you like this article, subscribe to our RSS Feed. You can also subscribe via email to our Interview Questions, Codes and Forums section.

Page copy protected against web site content infringement by Copyscape
Found interesting? Add this to:



Please Sign In to vote for this post.

About Abhishek Sur

Experience:3 year(s)
Home page:http://www.abhisheksur.com
Member since:Wednesday, December 02, 2009
Level:Silver
Status: [Member] [Microsoft_MVP] [MVP]
Biography:Working for last 2 and 1/2 years in .NET environment with profound knowledge on basics of most of the topics on it.
 Responses
Posted by: Abhijit Jana | Posted on: 11 Apr 2010 03:58:16 PM

Good Job Abhishek ! Keep it up !!

Posted by: Abhi2434 | Posted on: 11 Apr 2010 06:17:46 PM

Thank you so much Abhijit. Cheers.

>> Write Response - Respond to this post and get points
Related Posts

We will see how we can pass parameters to a WPF Click-Once Application and depends on the parameter we can use the application.

Technology is growing, everyday you will hear that there is a new version of something and you will wonder if we will ever stop learning. If you are a Microsoft developer you will always buy books because almost every three or two years they bring something and when you are still busy trying to master the current technology, they introduce something new that is better than this. The gap between .net 2.0 and 3.5 was enough to allow developers to catch up. Well I got affected by that but I kept on touching the chapters of those technologies. I was impressed by all these niceties but I could not have time to explore them all. I came across a WPF and I was impressed by the UI, even if you create a small hello world. I would like to share a small hello world about WPF.

Converter and ConverterParameter comes very handy while working with WPF Data Binding. You can manipulate the data bound to a value using IValueConverter. The article demonstrates how you can use it in your solution with a sample application.

It is a common problem to fix resolution related issues. Here I will demonstrate, how your UI will fix itself automatically using few tricks.

it's useful for beginners

More ...
About Us | Contact Us | The Team | Advertise | Software Development | Write for us | Testimonials | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you found plagiarised (copied) contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
Copyright © DotNetFunda.Com. All Rights Reserved. Copying or mimicking the site design and layout is prohibited. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks. | 5/21/2012 8:06:58 AM