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

Leave a Comment