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
Related videos on Youtube
Comments
-
Assaf almost 2 years
I am trying to use the SpellCheck class C# provides (in PresentationFramework.dll). But, I am experiencing problems when trying to bind the spelling to my textbox:
SpellCheck.SetIsEnabled(txtWhatever, true);
The problem is that my txtWhatever is of type System.Windows.Forms and the parameter this function is looking for is System.Windows.Controls, and simple converting failed. I also tried to make my TextBox of this type, but... couldn't. Does anyone know how to use this SpellCheck object? (MSDN wasn't that helpful...)
Thanks
-
Assaf over 13 yearsYes, i tried. System.Windows.Forms doesn't have this property probably. This is exactly my problem...
-
Assaf over 13 yearsI'm trying to implement your solution: What is the (s,e) part of the code means? Because I am getting a compiler error for it?
-
user1703401 over 13 yearsIt is a lambda expression, VS2008 required. Just delete it and let intellisense add a regular method instead.
-
user1703401 over 13 yearsErm, come to think of it, you have to have VS2008 if you use WPF?
-
Assaf over 13 yearsI'm using VS2005 and the WPF thing works - it is just not yet called WPF... and thanks for the help - the intellisense did its job.
-
Crag over 13 yearsThanks for posting this code. I converted it to VB.Net and it is working almost perfectly (still can't get the lambda/text changed event line to work at all, but I'm going to keep at it and get it eventually!).
-
Tuxmentat almost 13 yearsThank you for posting this sir, you have doubtlessly saved me many hours. :)
-
MDL about 12 yearsThank You! I'm voting this up for sure, you saved me money and wasted hours. Great Post!
-
Austin Henley over 11 yearsThis is more of a comment than an answer. Did you read the accepted answer?
-
Jack about 9 yearsThis isn't working for me and I have no idea why. The wrong word doesn't get underlined. At first the compiler claimed about an assembly reference not found but just adding
System.Xaml
referenced solved. But the spell still isn't working for me: prntscr.com/6rvwwk what am I missing? of course thattextBox
is yourSpellBox
. -
Jack about 9 yearsOk, I got it working. :) I set the language explicitly:
box.Language = System.Windows.Markup.XmlLanguage.GetLanguage("en-US");
. You also need to have the .NET language pack installed (but I had already). I'm not sure but this issue is probably due the fact the English isn't my OS' language. It working: prntscr.com/6rw50x -
TripVoltage almost 9 years@Hans great example many thanks. Just a quick question are we able to add custom words to the dictionary for the example you gave?
-
rrirower over 6 years@HansPassant - This is exactly what I need. However, I can't seem to figure out how to implement the TextChanged event. Do I code it in the SpellCheck class or my form?
-
rrirower over 6 years@HansPassant- Figured it out. I needed to dynamically add the events to my form. Thanks for your work.
-
OmarL over 5 years@Jack, did you ever figure out how that works exactly?
en-GB
doesn't work for me: it accepts "color" but marks "colour" as wrong. I'm expecting the opposite behaviour, which is what MS Word does on my system. -
Jack over 5 years@Wilson My experience with this wasn't good. I don't know the reason for this specific behavior, but from what I remember, it look up the words (the dictionary) from the files provided by the Windows/.NET framework but it support few languages. For example, installing the chinese pack language doesn't add Support for it. I think you're better off using some other implementation. I don't remember now the library I've used but I'm sure there are alot of good ones over internet. Pick one and anything ask here on SO.