Trying to Use the C# Spellcheck Class

Trying to use the C# SpellCheck class

You have to use a WPF TextBox to make spell checking work. You can embed one in a Windows Forms form with the ElementHost control. It works pretty similar to a UserControl. Here's a control that you can drop straight from the toolbox. To get started, you need Project + Add Reference and select WindowsFormsIntegration, System.Design and the WPF assemblies PresentationCore, PresentationFramework and WindowsBase.

Add a new class to your project and paste the code shown below. Compile. Drop the SpellBox control from the top of the toolbox onto a form. It supports the TextChanged event and the Multiline and WordWrap properties. There's a nagging problem with the Font, there is no easy way to map a WF Font to the WPF font properties. The easiest workaround for that is to set the form's Font to "Segoe UI", the default for WPF.

using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Forms.Design;

[Designer(typeof(ControlDesigner))]
//[DesignerSerializer("System.Windows.Forms.Design.ControlCodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
class SpellBox : ElementHost {
public SpellBox() {
box = new TextBox();
base.Child = box;
box.TextChanged += (s, e) => OnTextChanged(EventArgs.Empty);
box.SpellCheck.IsEnabled = true;
box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
this.Size = new System.Drawing.Size(100, 20);
}
public override string Text {
get { return box.Text; }
set { box.Text = value; }
}
[DefaultValue(false)]
public bool Multiline {
get { return box.AcceptsReturn; }
set { box.AcceptsReturn = value; }
}
[DefaultValue(false)]
public bool WordWrap {
get { return box.TextWrapping != TextWrapping.NoWrap; }
set { box.TextWrapping = value ? TextWrapping.Wrap : TextWrapping.NoWrap; }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new System.Windows.UIElement Child {
get { return base.Child; }
set { /* Do nothing to solve a problem with the serializer !! */ }
}
private TextBox box;
}

By popular demand, a VB.NET version of this code that avoids the lambda:

Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Forms.Integration
Imports System.Windows.Forms.Design

<Designer(GetType(ControlDesigner))> _
Class SpellBox
Inherits ElementHost

Public Sub New()
box = New TextBox()
MyBase.Child = box
AddHandler box.TextChanged, AddressOf box_TextChanged
box.SpellCheck.IsEnabled = True
box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto
Me.Size = New System.Drawing.Size(100, 20)
End Sub

Private Sub box_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
OnTextChanged(EventArgs.Empty)
End Sub

Public Overrides Property Text() As String
Get
Return box.Text
End Get
Set(ByVal value As String)
box.Text = value
End Set
End Property

<DefaultValue(False)> _
Public Property MultiLine() As Boolean
Get
Return box.AcceptsReturn
End Get
Set(ByVal value As Boolean)
box.AcceptsReturn = value
End Set
End Property

<DefaultValue(False)> _
Public Property WordWrap() As Boolean
Get
Return box.TextWrapping <> TextWrapping.NoWrap
End Get
Set(ByVal value As Boolean)
If value Then
box.TextWrapping = TextWrapping.Wrap
Else
box.TextWrapping = TextWrapping.NoWrap
End If
End Set
End Property

<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Shadows Property Child() As System.Windows.UIElement
Get
Return MyBase.Child
End Get
Set(ByVal value As System.Windows.UIElement)
'' Do nothing to solve a problem with the serializer !!
End Set
End Property
Private box As TextBox
End Class

SpellCheck Class In Code Behind

To solve your problem you can use the NHunspell library.

Your check method in this case is very simple and looks like this:

bool CheckSpell(string word)
{
using (Hunspell hunspell = new Hunspell("en_GB.aff", "en_GB.dic"))
{
return hunspell.Spell(word);
}
}

You can find dictionaries on this site.

Also you can use SpellCheck class:

bool CheckSpell(string word)
{
TextBox tb = new TextBox();
tb.Text = word;
tb.SpellCheck.IsEnabled = true;

int index = tb.GetNextSpellingErrorCharacterIndex(0, LogicalDirection.Forward);
if (index == -1)
return true;
else
return false;
}

Enable Spell Check on TextBox

You can try this: http://spellchecktextbox.codeplex.com . It uses the WPF control as a base.

//to answer your comment:

  1. open the tool project and build it.
  2. In your project right click the tool box(I usually do it under general.)
  3. Click choose items.
  4. Browse to TextBoxSource\obj\Debug
  5. Add the DLL ExtendedTextBox.dll

Also If the tool project is in another solution you will need to add the DLL to your references folder as well.

Edit:
I just realized you said you wanted German spell check. You will need to change this in the control project. Change:

 <TextBox SpellCheck.IsEnabled="True" Name="theTextBox" AcceptsReturn="True" AcceptsTab="True" Text="" Cursor="IBeam" CaretBrush="#E6000000" />

to something like

<TextBox SpellCheck.IsEnabled="True" Name="theTextBox" AcceptsReturn="True" AcceptsTab="True" Text="" Cursor="IBeam" CaretBrush="#E6000000" xml:lang="German Culture Code here"/>

How to activate spellCheck in C# Windows Form Application?

If you are using .net4 you can add the References System.Xaml and WindowsFormsIntegration to your Winforms project.

This allows you to find the ElementHost in you Toolbox. By using the ElementHost you can use WPF objects in your Winfroms project.

System.Windows.Forms.Integration.ElementHost elementHost1 = new System.Windows.Forms.Integration.ElementHost();
System.Windows.Controls.TextBox textBox = new System.Windows.Controls.TextBox();
textBox.SpellCheck.IsEnabled = true;
elementHost1.Child = textBox;

using SpellCheck with Windows Forms .... is it possible to rig one up to a datagridview text cell?


private void button1_Click(object sender, EventArgs e)
{
Word.Application app = new Word.Application();
int errors = 0;
if (tx_article_title.Text.Length > 0)
{
app.Visible = false;
// Setting these variables is comparable to passing null to the function.
// This is necessary because the C# null cannot be passed by reference.
object template = Missing.Value;
object newTemplate = Missing.Value;
object documentType = Missing.Value;
object visible = true;
// object visible = false;
Word._Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
doc1.Words.First.InsertBefore(tx_article_title.Text);
Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
errors = spellErrorsColl.Count;
object optional = Missing.Value;
doc1.Activate();
this.Opacity = 0;
//// get test form's handler
//IntPtr hwnd = this.Handle;
//// wait until the test form is the foreground window
//while (true)
//{
// if (GetForegroundWindow() == hwnd)
// break;
//}
//// Thread.Sleep(2000);

// create a new thread to get the spelling check dialog
//Thread t = new Thread(new ThreadStart(GetSpellcheckingHandle));
//t.Start();
doc1.CheckSpelling(
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional,
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional);
this.Opacity = 1;
object first = 0;
object last = doc1.Characters.Count - 1;
tx_article_title.Text = doc1.Range(ref first, ref last).Text;
}
if (tx_author.Text.Length > 0)
{
app.Visible = false;
// Setting these variables is comparable to passing null to the function.
// This is necessary because the C# null cannot be passed by reference.
object template = Missing.Value;
object newTemplate = Missing.Value;
object documentType = Missing.Value;
object visible = true;
// object visible = false;
Word._Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
doc1.Words.First.InsertBefore(tx_author.Text);
Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
errors = spellErrorsColl.Count;
object optional = Missing.Value;
doc1.Activate();
this.Opacity = 0;
//// get test form's handler
//IntPtr hwnd = this.Handle;
//// wait until the test form is the foreground window
//while (true)
//{
// if (GetForegroundWindow() == hwnd)
// break;
//}
//// Thread.Sleep(2000);

// create a new thread to get the spelling check dialog
//Thread t = new Thread(new ThreadStart(GetSpellcheckingHandle));
//t.Start();
doc1.CheckSpelling(
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional,
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional);
this.Opacity = 1;
object first = 0;
object last = doc1.Characters.Count - 1;
tx_author.Text = doc1.Range(ref first, ref last).Text;
}
if (tx_region.Text.Length > 0)
{
app.Visible = false;
// Setting these variables is comparable to passing null to the function.
// This is necessary because the C# null cannot be passed by reference.
object template = Missing.Value;
object newTemplate = Missing.Value;
object documentType = Missing.Value;
object visible = true;
// object visible = false;

Word._Document doc1 = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);
doc1.Words.First.InsertBefore(tx_region.Text);
Word.ProofreadingErrors spellErrorsColl = doc1.SpellingErrors;
errors = spellErrorsColl.Count;
object optional = Missing.Value;
doc1.Activate();
this.Opacity = 0;
//// get test form's handler
//IntPtr hwnd = this.Handle;
//// wait until the test form is the foreground window
//while (true)
//{
// if (GetForegroundWindow() == hwnd)
// break;
//}
//// Thread.Sleep(2000);

// create a new thread to get the spelling check dialog
Thread t = new Thread(new ThreadStart(GetSpellcheckingHandle));
t.Start();
doc1.CheckSpelling(
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional,
ref optional, ref optional, ref optional, ref optional, ref optional, ref optional);
this.Opacity = 1;
object first = 0;
object last = doc1.Characters.Count - 1;
tx_region.Text = doc1.Range(ref first, ref last).Text;
}
object saveChanges = false;
object originalFormat = Missing.Value;
object routeDocument = Missing.Value;
app.Quit(ref saveChanges, ref originalFormat, ref routeDocument);
MessageBox.Show("SpellCheck completed!");
this.Activate();
}

/// <summary>
/// get the spelling check handle
/// </summary>
public void GetSpellcheckingHandle()
{
int i = FindWindow("bosa_sdm_msword", (int)IntPtr.Zero);
while (i != 0)
{
// bring the spelling check dialog to the front.
BringToFront("bosa_sdm_msword", (int)IntPtr.Zero);
}

}
}

This could be helped.

.NET Spell Check control?

Not a redlining control, but: Aspell.Net is a Free and Open Source .Net spell checking component. Based on the GNU Aspell project, Aspell.Net is one of the most powerful multi-lingual spelling engines available. The API is written in C# and communicates through a C++ wrapper around the Win32 Port of Aspell's C API.

Source repository at sourceforge, checked February 2010 (Tahnks, @magnifico).

May 2012, source no longer accessible... sorry.

how to add spellcheck in framework 3.5

As @Sinatr has write to you in comments - you can't use WPF Spellchecking in WinForms application.

In WinForms you need add some library. For example you can try use offline The NetSpell project It's a little bit old library. Or you can use newer but still beta Spell Check Winforms TextBox

UPDATE:
NetSpell is free. You can find manual by this link NetSpell - Spell Checker for .NET in Using the Library section.

There is also possibility to add in your WinForms application control named ElementHost. It will allow you to insert in your application WPF TextBox. And you will be able to set SpellCheck.IsEnabled property for this TextBox inside ElementHost.

Here is nice link about ElementHost: Hosting WPF controls in a WinForms application

Where can I find a free, easy to implement spellcheck component for .NET?

You should check out NetSpell, very easy to implement.

Link to an example
http://www.codeproject.com/KB/string/netspell.aspx



Related Topics



Leave a reply



Submit