# Add SpellChecking in FlexGrid

## Content

To spell-check other types of controls (a grid for example), you have to create a wrapper class that implements the <span data-popup-content="This class is available in both \u003ca href=\u0022/componentone/docs/win/online-spellchecker/\u0022\u003e.NET\u003c/a\u003e and \u003ca href=\u0022/componentone/docs/win/online-spellchecker/\u0022\u003e.NET Framework\u003c/a\u003e assemblies." data-popup-title="ISpellCheckableEditor" data-popup-theme="ui-tooltip-green qtip-green">ISpellCheckableEditor</span> interface or the **ISpellCheckableRichEditor** interface. To do this, complete the following steps:

1. First, add the necessary controls and set some basic properties:
    a. From the Toolbox, add the **C1SpellChecker** component, **C1FlexGrid** control, and **Button** control to your form. Note that the **C1SpellChecker** component will appear in the component tray.
    b. Arrange the grid and button controls on the Form.
    c. Select the **Button** control and set its **Text** property to **Spell-Check the Grid** in the Properties window.
    d. Select the **C1FlexGrid** control and set its **Name** property to **\_flex**.
    e. Select the **C1SpellChecker** control and set its **Name** property to **\_spell**.
    f. Select the Form and set its **Name** property to **FlexGridForm**.
2. To specify the namespaces used in this example, add the following statements before any declarations in the Code Editor:

    ```csharp
    using System.Data.OleDb;
    using C1.Win.C1FlexGrid;
    using C1.Win.C1SpellChecker;
    ```

    ```vbnet
    Imports System.Data.OleDb
    Imports C1.Win.C1FlexGrid
    Imports C1.Win.C1SpellChecker
    ```
3. To initialize the grid, double-click the Form and add the following code to the **FlexGridForm\_Load** event. Note that you may have to change the connection string slightly, because it has a reference to the C1NWind.mdb database and that file might be in a different folder in your system:

    ```csharp
    // Load data
    string sql = "select * from employees";
    string conn = @"provider=microsoft.jet.oledb.4.0;data source=C:\Users\<User Name>\Documents\ComponentOne Samples\Common\C1NWind.mdb;";
    OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
    DataTable dt = new DataTable();
    da.Fill(dt);
     // Initialize grid
    _flex.Styles.Normal.WordWrap = true;
    _flex.DataSource = dt;
    Column c = _flex.Cols["Notes"];
    c.Width = 350;
    _flex.AutoSizeRows();
     // Hook up spell-checker when editing starts
    _flex.StartEdit += new RowColEventHandler(_flex_StartEdit);
     // Use green underline here, just for fun
    _spell.Options.UnderlineColor = Color.DarkGreen;
    ```

    ```vbnet
    ' Load data
    Dim sql As String = "select * from employees"
    Dim conn As String = "provider=microsoft.jet.oledb.4.0;data source=C:\Users\<User Name>\Documents\ComponentOne Samples\Common\C1NWind.mdb;"
    Dim da As New OleDbDataAdapter(sql, conn)
    Dim dt As New DataTable()
    da.Fill(dt)
     ' Initialize grid
    _flex.Styles.Normal.WordWrap = True
    _flex.DataSource = dt
    Dim c As Column = _flex.Cols("Notes")
    c.Width = 350
    _flex.AutoSizeRows()
     ' Hook up spell-checker when editing starts
    AddHandler _flex.StartEdit, AddressOf _flex_StartEdit
     ' Use green underline here, just for fun
    _spell.Options.UnderlineColor = Color.DarkGreen
    ```
4. Add the **StartEdit** event to the **C1FlexGrid** control and then add the following code inside the *flex*\_StartEdit event. The **SetSpellChecking** method is used to provide as-your type spelling in the grid editor.

    ```csharp
    // Provide as-you-type spelling in the grid editor
    void _flex_StartEdit(object sender, RowColEventArgs e)
    {
        TextBoxBase tb = _flex.Editor as TextBoxBase;
        if (tb != null)
        {
            _spell.SetSpellChecking(tb, true);
        }
    }
    ```

    ```vbnet
    ' Provide as-you-type spelling in the grid editor
    Private Sub _flex_StartEdit(ByVal sender As Object, ByVal e As RowColEventArgs)
        Dim tb As TextBoxBase = TryCast(_flex.Editor, TextBoxBase)
        If tb IsNot Nothing Then
            _spell.SetSpellChecking(tb, True)
        End If
    End Sub
    ```
5. To spell-check the grid, double-click the **Button** control and add the following code to the **Button\_Click** event:

    ```csharp
    // Create spell-checkable wrapper for C1FlexGrid
    FlexGridSpeller editor = new FlexGridSpeller(_flex, "Title", "Notes");
     // spell-check
    int errorCount = _spell.CheckControl(editor);
     if (errorCount > -1)
      {
         string msg = string.Format("Spell-checking complete. {0} error(s) found.", errorCount);
         MessageBox.Show(msg);
      }
    else
    {
        MessageBox.Show("Spell-checking cancelled.");
    }
    ```

    ```vbnet
    ' Create spell-checkable wrapper for C1FlexGrid
    Dim editor As New FlexGridSpeller(_flex, "Title", "Notes")
     ' spell-check
    Dim errorCount As Integer = _spell.CheckControl(editor)
    If errorCount > -1 Then
        Dim msg As String = String.Format("Spell-checking complete. {0} error(s) found.", errorCount)
        MessageBox.Show(msg)
    Else
        MessageBox.Show("Spell-checking cancelled.")
    End If
    ```
6. Add the following code to create a wrapper class that implements the ISpellCheckableEditor interface:

    ```csharp
    public class FlexGridSpeller : ISpellCheckableEditor
    {
        //-------------------------------
        #region ** fields
         // Grid being spell-checked
        C1FlexGrid _flex;
        // Columns to be spell-checked
        int[] _cols;
        // Cell being spell-checked (_row, _cols[_col])
        int _row, _col;
        // Selection being checked within the cell
        int _selStart;
        int _selLength;
         #endregion
        //-------------------------------
        #region ** ctors
         // Check some columns
        public FlexGridSpeller(C1FlexGrid flex, params string[] cols)
        {
            // Save parameters
            _flex = flex;
             // Create column list if needed
            if (cols == null)
            {
                List list = new List();
                foreach (Column col in flex.Cols)
                {
                    if (col.DataType == typeof(string))
                        list.Add(col.Name);
                }
                cols = list.ToArray();
            }
             // Convert column names to column indices
            _cols = new int[cols.Length];
            for (int i = 0; i < _cols.Length; i++)
            {
                string name = cols[i];
                if (!_flex.Cols.Contains(name))
                {
                    throw new Exception("column not found: " + name);
                }
                _cols[i] = _flex.Cols[name].Index;
            }
                // Scan cells until an error is found
                _row = -1;
                _col = 0;
                MoveNext();
        }
         // Check all columns
        public FlexGridSpeller(C1FlexGrid flex)
            : this(flex, null)
        {
        }
         #endregion
         //-------------------------------
        #region ** object model
         // move on to the next cell
        public bool MoveNext()
        {
            // Initialize or increment row/col position
            if (_row < 0)
            {
                // initialize
                _row = _flex.Rows.Fixed;
                _col = 0;
            }
            else if (_col < _cols.Length - 1)
            {
                // next column
                _col++;
            }
            else
            {
                // next row
                _row++;
                _col = 0;
            }
            // Return true if we still have valid cells
            return _row < _flex.Rows.Count && _col < _cols.Length;
        }
         #endregion
         //-------------------------------
        #region ** ISpellCheckableEditor
         public Control Control
        {
            get { return _flex; }
        }
        public bool HideSelection
        {
            get { return false; }
            set { }
        }
        public string Text
        {
            get { return _flex.GetDataDisplay(_row, _cols[_col]); }
            set { _flex[_row, _cols[_col]] = value; }
        }
        public string SelectedText
        {
            get { return Text.Substring(_selStart, _selLength); }
            set
            {
                string text = Text;
                text = string.Format("{0}{1}{2}",
                    text.Substring(0, _selStart),
                    value,
                    text.Substring(_selStart + _selLength));
                Text = text;
            }
        }
        public int SelectionLength
        {
            get { return _selLength; }
            set { _selLength = value; }
        }
        public int SelectionStart
        {
            get { return _selStart; }
            set { _selStart = value; }
        }
        public void Select(int start, int length)
        {
            // Keep track of selection within the cell
            _selStart = start;
            _selLength = length;
            // Check that the cell being checked is selected
            _flex.Select(_row, _cols[_col]);
        }
        public void SelectAll()
        {
            _selStart = 0;
            _selLength = Text.Length;
        }
        public bool HasMoreText()
        {
            return MoveNext();
        }
        public void BeginSpell()
        {
        }
        public void EndSpell()
        {
        }
        #endregion
    }
    ```

    ```vbnet
    Public Class FlexGridSpeller
    Implements ISpellCheckableEditor
    '-------------------------------
    #Region "** fields"
         Private _flex As C1FlexGrid
        ' Grid being spell-checked
        Private _cols As Integer()
        ' Columns to be spell-checked
        Private _row As Integer, _col As Integer
        ' Cell being spell-checked (_row, _cols[_col])
        Private _selStart As Integer
        ' Selection being checked within the cell
        Private _selLength As Integer
     #End Region
    '-------------------------------
    #Region "** ctors"
         ' Check some columns
        Public Sub New(ByVal flex As C1FlexGrid, ByVal ParamArray cols As String())
            ' save parameters
            _flex = flex
             ' Create column list if needed
            If cols Is Nothing Then
                Dim list As New List(Of String)()
                For Each col As Column In flex.Cols
                    If col.DataType.ToString() = "String" Then
                        list.Add(col.Name)
                    End If
                Next
                cols = list.ToArray()
            End If
             ' Convert column names to column indices
            _cols = New Integer(cols.Length - 1) {}
            For i As Integer = 0 To _cols.Length - 1
                Dim name As String = cols(i)
                If Not _flex.Cols.Contains(name) Then
                    Throw New Exception("column not found: " + name)
                End If
                _cols(i) = _flex.Cols(name).Index
            Next
             ' Scan cells until an error is found
            _row = -1
            _col = 0
            MoveNext()
        End Sub
         ' Check all columns
        Public Sub New(ByVal flex As C1FlexGrid)
            Me.New(flex, Nothing)
        End Sub
     #End Region
         '-------------------------------
    #Region "** object model"
         ' Move on to the next cell
        Public Function MoveNext() As Boolean
            ' initialize or increment row/col position
            If _row < 0 Then
                ' initialize
                _row = _flex.Rows.Fixed
                _col = 0
            ElseIf _col < _cols.Length - 1 Then
                ' next column
                _col += 1
            Else
                ' next row
                _row += 1
                _col = 0
            End If
             ' return true if we still have valid cells
            Return _row < _flex.Rows.Count AndAlso _col < _cols.Length
        End Function
     #End Region
         '-------------------------------
    #Region "** ISpellCheckableEditor"
         Public ReadOnly Property Control() As Control Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.Control
            Get
                Return _flex
            End Get
        End Property
        Public Property HideSelection() As Boolean Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.HideSelection
            Get
                Return False
            End Get
            Set(ByVal value As Boolean)
            End Set
        End Property
        Public Property Text() As String Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.Text
            Get
                Return _flex.GetDataDisplay(_row, _cols(_col))
            End Get
            Set(ByVal value As String)
                _flex(_row, _cols(_col)) = value
            End Set
        End Property
        Public Property SelectedText() As String Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.SelectedText
            Get
                Return Text.Substring(_selStart, _selLength)
            End Get
            Set(ByVal value As String)
                Dim t As String = Text
                t = String.Format("{0}{1}{2}", _
                    Text.Substring(0, _selStart), _
                    value, _
                    Text.Substring(_selStart + _selLength))
                Text = t
            End Set
        End Property
        Public Property SelectionLength() As Integer Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.SelectionLength
            Get
                Return _selLength
            End Get
            Set(ByVal value As Integer)
                _selLength = value
            End Set
        End Property
        Public Property SelectionStart() As Integer Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.SelectionStart
            Get
                Return _selStart
            End Get
            Set(ByVal value As Integer)
                _selStart = value
            End Set
        End Property
        Public Sub [Select](ByVal start As Integer, ByVal length As Integer) Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.Select
            ' Keep track of selection within the cell
            _selStart = start
            _selLength = length
             ' Check that the cell being checked is selected
            _flex.[Select](_row, _cols(_col))
        End Sub
        Public Sub SelectAll()
            _selStart = 0
            _selLength = Text.Length
        End Sub
        Public Function HasMoreText() As Boolean Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.HasMoreText
            Return MoveNext()
        End Function
        Public Sub BeginSpell() Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.BeginSpell
         End Sub
        Public Sub EndSpell() Implements C1.Win.C1SpellChecker.ISpellCheckableEditor.EndSpell
        End Sub
    #End Region
    End Class
    ```