シフト JIS で使用できない文字の入力を禁止するには?
対象製品
MultiRow for Windows Forms 5.0J
詳細
サロゲートペア、結合文字、JIS2004のようにシフトJISで使用できないUnicode文字の入力を禁止するには、入力された文字列とシフトJISへの変換結果を比較し、一致しない場合に検証エラーにします。
次のコードは、GcMultiRowコントロールのセル検証イベントを使用した実装例です。たとえば、JIS2004を入力できる環境で「もりおうがい」と入力し、「森おう外(おうは変換候補の一覧から環境依存文字を選択)」と変換し、Enterキーでセルの編集を確定、Tabキーまたはマウス操作で次のセルに移動しようとすると、セルの検証がエラーになります。
[Visual Basic]
[C#]
次のコードは、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 GrapeCity.Win.MultiRow.CellValidatingEventArgs) Handles GcMultiRow1.CellValidating
Dim gcMultiRow As GcMultiRow = TryCast(sender, GcMultiRow)
If TypeOf gcMultiRow.Rows(e.RowIndex).Cells(e.CellIndex) Is TextBoxCell AndAlso Not e.FormattedValue Is 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 GrapeCity.Win.MultiRow.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
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 GrapeCity.Win.MultiRow.CellValidatingEventArgs) Handles GcMultiRow1.CellValidating
Dim gcMultiRow As GcMultiRow = TryCast(sender, GcMultiRow)
If TypeOf gcMultiRow.Rows(e.RowIndex).Cells(e.CellIndex) Is TextBoxCell AndAlso Not e.FormattedValue Is 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 GrapeCity.Win.MultiRow.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, GrapeCity.Win.MultiRow.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 = "";
}
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, GrapeCity.Win.MultiRow.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 = "";
}
この文書は、以前は次のFAQ IDで公開されていました : 12711