- 題名: 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に設定した場合も発生しないようです。
【解決するために何をしたか】
多くのサイトを調べましたが、同様の現象に悩む記事がありませんでした。