- 題名: DataGridViewに全角文字で長文を改行ありで入力するとフリーズする
- 日時: 2009/03/18 20:13:33
- ID: 24227
- この記事の返信元:
- (なし)
- この記事への返信:
- [24253] Re[1]: DataGridViewに全角文字で長文を改行ありで入力するとフリーズする2009/03/20 19:46:51
- ツリーを表示
原因は私にも分かりかねますが、 私のPC(CeleronM1.5Ghz)でも同じ現象を確認しました。 そこで1つの回避策として、 Textの編集と表示の最小限の機能のみを持つCellを自作したところ、 かなり動作が軽くなりました。 これが正しい書き方なのかは分かりませんし、 何か実装漏れがあるかもしれませんが、 私のPCではTextの編集、設定、表示が正しく動作しています。 以下のコードで試してみてください。 ''' <summary>テスト用Form</summary> Public Class DataGridViewTextBoxLongStringTestForm Inherits Form ' DataGridView Dim WithEvents _dgv As New DataGridView ' デバッグプリント用Button Dim WithEvents _btnDebug As New Button With {.Location = New Point(180, 200), .Width = 100, .Text = "DebugPrint"} Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) ' DataGridView初期化 With Me._dgv .Dock = DockStyle.Fill Dim col As New MyTextBoxColumn col.Name = "Text列" col.DefaultCellStyle.WrapMode = DataGridViewTriState.True .Columns.Add(col) .RowCount = 10 ' セルにサンプルTextを代入 For Each dr As DataGridViewRow In .Rows dr.Cells(0).Value = dr.Index.ToString + " - " + New String("あ"c, 10000) Next End With Me.Controls.Add(Me._btnDebug) Me.Controls.Add(Me._dgv) MyBase.OnLoad(e) End Sub Private Sub _dgv_EditingControlShowing(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles _dgv.EditingControlShowing Console.WriteLine("EditingControlShowing") End Sub ''' <summary>デバッグプリント:各セルの先頭10文字を表示</summary> Private Sub _btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _btnDebug.Click For i As Integer = 0 To Me._dgv.Rows.Count - 1 Dim ss As String = Convert.ToString(Me._dgv.Rows(i).Cells(0).Value) Console.WriteLine(ss.Substring(0, Math.Min(10, ss.Length))) Next End Sub End Class ''' <summary>自作TextBoxColumn</summary> Public Class MyTextBoxColumn Inherits DataGridViewColumn Public Overrides Property CellTemplate() As System.Windows.Forms.DataGridViewCell Get Return New MyTextBoxCell End Get Set(ByVal value As System.Windows.Forms.DataGridViewCell) MyBase.CellTemplate = value End Set End Property End Class ''' <summary>自作TextBoxColumnのCell</summary> Public Class MyTextBoxCell Inherits DataGridViewCell ''' <summary>Cellの内容を画面に描画する</summary> Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, _ ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, _ ByVal rowIndex As Integer, ByVal cellState As System.Windows.Forms.DataGridViewElementStates, _ ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, _ ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, _ ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, _ ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts) Dim foreBrush, backBrush As Brush If Me.Selected Then foreBrush = SystemBrushes.HighlightText backBrush = SystemBrushes.Highlight Else foreBrush = SystemBrushes.WindowText backBrush = SystemBrushes.Window End If graphics.FillRectangle(backBrush, cellBounds) Using p As New Pen(Color.LightGray) graphics.DrawRectangle(p, cellBounds) End Using graphics.DrawString(Convert.ToString(Me.Value), Me.DataGridView.Font, foreBrush, cellBounds) End Sub Public Overrides ReadOnly Property FormattedValueType() As System.Type Get Return GetType(String) End Get End Property Public Overrides Property ValueType() As System.Type Get Return GetType(String) End Get Set(ByVal value As System.Type) MyBase.ValueType = value End Set End Property ''' <summary>編集コントロールは、既存のものをそのまま利用する</summary> Public Overrides ReadOnly Property EditType() As System.Type Get Return GetType(DataGridViewTextBoxEditingControl) End Get End Property ''' <summary>ダブルクリックで編集モードに入る</summary> Protected Overrides Sub OnDoubleClick(ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Me.DataGridView.BeginEdit(True) MyBase.OnDoubleClick(e) End Sub ''' <summary>編集モードに入る時に、TextBoxにCellの内容をコピーする</summary> Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, _ ByVal dataGridViewCellStyle As System.Windows.Forms.DataGridViewCellStyle) Dim tbx As TextBox = DirectCast(Me.DataGridView.EditingControl, TextBox) tbx.Multiline = True tbx.ScrollBars = ScrollBars.Vertical tbx.Size = Me.Size tbx.Text = Convert.ToString(Me.Value) MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle) End Sub End Class
分類:[.NET]
【解決したい問題】
DataGridViewの1セルに5000文字以上の文字を入力する必要があるプログラムを作成しています。
1セルに数千の文字(全角)を入力した場合、入力後再度入力したセルをクリックした際になど、CPUの使用率が100%になり、フリーズしてしまいます。
再現方法としては、DataGridViewをFormに配置し、TextBoxのカラムを1列追加します。
DataGridViewのプロパティの設定は、DataGridViewCellStyleのWrapModeをTrueに設定しているだけです。
実行後、TextBoxのセルに全角文字でデフォルトの最大文字数を入力します。
入力後、enterを押下した場合や他のセルを選択後、入力したセルをクリックした場合に、CPU使用率が100%になったまま、フリーズしてしまいます。
最大文字数の32767文字以下でもCPUが100%の状態になっている時間の程度は異なりますが、発生します。
また、該当セルの行の高さを高くし、より多くの文字列が表示されるようにすると発生しやすくなります。
半角文字の場合だと発生しないようです。
また、WrapModeをFalseに設定した場合も発生しないようです。
【解決するために何をしたか】
多くのサイトを調べましたが、同様の現象に悩む記事がありませんでした。