シフト JISで使用できない文字の入力を禁止するには?
対象製品
MultiRow for Windows Forms 8.0J
詳細
サロゲートペア、結合文字、JIS2004のようにシフトJISで使用できないUnicode文字の入力を禁止するには、入力された文字列とシフトJISへの変換結果を比較し、一致しない場合に検証エラーにします。
次のコードは、GcMultiRowコントロールのセル検証イベントを使用した実装例です。たとえば、JIS2004を入力できる環境で「もりおうがい」と入力し、「森おう外(おうは変換候補の一覧から環境依存文字を選択)」と変換し、Enterキーでセルの編集を確定、Tabキーまたはマウス操作で次のセルに移動しようとすると、セルの検証がエラーになります。
[Visual Basic]
[C#]
参考:
InputManCellのGcTextBoxCellを使用すると、数字やカナ、アルファベットや記号などのほかに、以下の文字に対して入力を制限することができます。
文字の入力制限は、GcTextBoxCell.Formatプロパティに該当するキーワードを設定することで実現します。
次のコードは、GcMultiRowコントロールのセル検証イベントを使用した実装例です。たとえば、JIS2004を入力できる環境で「もりおうがい」と入力し、「森おう外(おうは変換候補の一覧から環境依存文字を選択)」と変換し、Enterキーでセルの編集を確定、Tabキーまたはマウス操作で次のセルに移動しようとすると、セルの検証がエラーになります。
[Visual Basic]
Imports System.Globalization Imports System.Text Imports GrapeCity.Win.MultiRow Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load GcMultiRow1.Template = Template.Default End Sub Private Sub GcMultiRow1_CellValidating(ByVal sender As System.Object, ByVal e As CellValidatingEventArgs) Handles GcMultiRow1.CellValidating Dim gcMultiRow As GcMultiRow = TryCast(sender, GcMultiRow) If TypeOf gcMultiRow.Rows(e.RowIndex).Cells(e.CellIndex) Is TextBoxCell AndAlso e.FormattedValue IsNot Nothing Then Dim sjis As Encoding = Encoding.GetEncoding("Shift_JIS") Dim formattedString As String = DirectCast(e.FormattedValue, String) Console.WriteLine(formattedString) Dim bytes As Byte() = sjis.GetBytes(formattedString) Dim sjisString As String = sjis.GetString(bytes) If Not sjisString = formattedString Then Dim diff As Integer = CompareStrings(formattedString, sjisString) Dim invalidString As String = StringInfo.GetNextTextElement(formattedString, diff) gcMultiRow.Rows(e.RowIndex).Cells(e.CellIndex).ErrorText = String.Format("'{0}' はシフトJISで使用できない文字です。", invalidString) e.Cancel = True End If End If End Sub ''' <summary> ''' 指定した 2 つの String オブジェクトを比較し、最初に見つかった異なる文字の位置を示す整数を返します。 ''' </summary> ''' <param name="strA">第1の String</param> ''' <param name="strB">第2の String</param> ''' <returns>最初に見つかった異なる文字の位置。文字列が同じ場合は-1。</returns> Private Function CompareStrings(ByVal strA As String, ByVal strB As String) As Integer Dim a As Char() = strA.ToCharArray() Dim b As Char() = strB.ToCharArray() For i As Integer = 0 To a.Length - 1 If Not a(i) = b(i) Then Return i Next Return -1 End Function Private Sub GcMultiRow1_CellValidated(ByVal sender As System.Object, ByVal e As GrapeCity.Win.MultiRow.CellEventArgs) Handles GcMultiRow1.CellValidated Dim gcMultiRow As GcMultiRow = TryCast(sender, GcMultiRow) gcMultiRow.Rows(e.RowIndex).Cells(e.CellIndex).ErrorText = "" End Sub Private Sub GcMultiRow1_EditingControlShowing(ByVal sender As System.Object, ByVal e As EditingControlShowingEventArgs) Handles GcMultiRow1.EditingControlShowing If TypeOf e.Control Is TextBoxEditingControl Then RemoveHandler e.Control.TextChanged, AddressOf TextBoxEditingControl_TextChanged AddHandler e.Control.TextChanged, AddressOf TextBoxEditingControl_TextChanged End If End Sub Private Sub TextBoxEditingControl_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Dim textBoxEditingControl As TextBoxEditingControl = TryCast(sender, TextBoxEditingControl) textBoxEditingControl.GcMultiRow.CurrentCell.ErrorText = "" End Sub
[C#]
using System.Globalization; using GrapeCity.Win.MultiRow; private void Form1_Load(object sender, EventArgs e) { gcMultiRow1.Template = Template.Default; gcMultiRow1.CellValidating += new EventHandler<CellValidatingEventArgs>(gcMultiRow1_CellValidating); gcMultiRow1.CellValidated += new EventHandler<CellEventArgs>(gcMultiRow1_CellValidated); gcMultiRow1.EditingControlShowing += new EventHandler<EditingControlShowingEventArgs>(gcMultiRow1_EditingControlShowing); } private void gcMultiRow1_CellValidating(object sender, GrapeCity.Win.MultiRow.CellValidatingEventArgs e) { GcMultiRow gcMultiRow = sender as GcMultiRow; if (gcMultiRow.Rows[e.RowIndex].Cells[e.CellIndex] is TextBoxCell && e.FormattedValue != null) { Encoding sjis = Encoding.GetEncoding("Shift_JIS"); string formattedString = (string)e.FormattedValue; byte[] bytes = sjis.GetBytes(formattedString); string sjisString = sjis.GetString(bytes); if (sjisString != formattedString) { int diff = CompareStrings(formattedString, sjisString); string invalidString = StringInfo.GetNextTextElement(formattedString, diff); gcMultiRow.Rows[e.RowIndex].Cells[e.CellIndex].ErrorText = string.Format("'{0}' はシフトJISで使用できない文字です。", invalidString); e.Cancel = true; } } } /// <summary> /// 指定した 2 つの String オブジェクトを比較し、最初に見つかった異なる文字の位置を示す整数を返します。 /// </summary> /// <param name="strA">第1の String</param> /// <param name="strB">第2の String</param> /// <returns>最初に見つかった異なる文字の位置。文字列が同じ場合は-1。</returns> private int CompareStrings(string strA, string strB) { char[] a = strA.ToCharArray(); char[] b = strB.ToCharArray(); for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) return i; } return -1; } private void gcMultiRow1_CellValidated(object sender, CellEventArgs e) { GcMultiRow gcMultiRow = sender as GcMultiRow; gcMultiRow.Rows[e.RowIndex].Cells[e.CellIndex].ErrorText = ""; } private void gcMultiRow1_EditingControlShowing(object sender, EditingControlShowingEventArgs e) { if (e.Control is TextBoxEditingControl) { e.Control.TextChanged -= new EventHandler(TextBoxEditingControl_TextChanged); e.Control.TextChanged += new EventHandler(TextBoxEditingControl_TextChanged); } } private void TextBoxEditingControl_TextChanged(object sender, EventArgs e) { TextBoxEditingControl textBoxEditingControl = sender as TextBoxEditingControl; textBoxEditingControl.GcMultiRow.CurrentCell.ErrorText = ""; }
参考:
InputManCellのGcTextBoxCellを使用すると、数字やカナ、アルファベットや記号などのほかに、以下の文字に対して入力を制限することができます。
文字の入力制限は、GcTextBoxCell.Formatプロパティに該当するキーワードを設定することで実現します。
- サロゲート ペア文字
- 2バイト文字(サロゲート ペア文字を除いた全角文字)
- JIS X 0208で構成された文字
- Shift JIS(CP932)で構成された文字
- IVS(Ideographic Variation Sequence)文字