.NET Windows窗体DataGridView以编程方式添加时,单元格文本消失

我正在开发一个包含DataGridView的Windows窗体应用程序。 这个DataGridView有3列,所有列都只是文本单元格:

  • Timestamp
  • Connection
  • Message

我遇到的问题是,当我添加一行(以编程方式)时,我发现如果文本太长,文本就会消失。 具体来说,如果文本长度超过4563个字符,则文本消失。

我知道DataGridViewTextBoxColumn类有一个属性调用MaxInputLength ,它可以限制输入的字符数。 但根据文档 ,它只影响用户手动输入的文本。 但是,我正在以编程方式输入此文本。

但是为了确保,我将此属性设置得非常高,但是当我通过4563字符限制时,仍会出现消失的文本问题。

我注意到的一件事是文本仍然存在(即底部的滚动条仍然可以滚动,就好像文本仍在那里)但我看不到文本本身。 我也可以编辑文本。

我可以添加字符直到4563限制,但是一旦我通过它,文本就会消失。 如果按退格键返回正好4563个字符, 则会再次出现该文本。

我正在使用.NET 4.0进行开发,因为我必须支持Windows XP。

这是简短的答案,可能会令你失望:这是一个报告的错误并经过微软validation,关闭为“不够重要,无法解决”。 可能会有更多的实例,但是至少2011年DataGridView控件显示空白单元格,如果输入大字符串并且列大小调整为最大值 ,则可以知道它。 “解决方法”是仅限制单元格宽度的大小,但对于您来说可能并不令人满意。

然而,好奇心得到了我的好处,所以我开始深入研究它; 这是第一个值得一提的观察:

在此处输入图像描述

如果你看一系列的图片,你会发现我用默认的字体大小/样式和特定的数字5460复制了你的问题。5460有什么特别之处? 好吧,没什么特别的,除了当你的角色阈值越过它时,列的ContentBounds和Width传递32767. 32767有什么特别之处? 除了作为DataGridViewTextBoxCell的默认MaxInputLength ,它还是有符号short或Int16(2 ^ 15-1)的上限。 我非常怀疑这里出现的问题是巧合,尽管这与MaxInputLength本身没有任何关系。 我愿意打赌你首先注意到4563个字符的问题,因为你的字体大小也将宽度扩展到32767。

接下来的问题是,为什么? 我不太确定。 我开始关注兔子洞并拆解了一些.NET 4.0 DataGridView *库以找出答案。 这是一个非常庞大而复杂的控制,我无法得出任何明确的结论,但有一件事我发现值得注意的是列可以假设的绝对最大宽度为65536,即UN64的Int16的值(2 ^ 16):

在此处输入图像描述

在添加或调整列时,您会在很多私有内部位置看到此检查,并且我对其进行了测试。 尺寸不会变大

具有讽刺意味的是有两个原因。 例如,使用默认设置,尽管编辑输入长度为32767个字符,并且在编程上是任意的,但您只能在列中显示10922个字符(每个字符65536/6像素)。

其次,为什么这个问题会在最大列宽最大值的最大值处开始出现? Hmmmm。 这完全是一个猜测,但我认为沿着这条线的某个地方,任何渲染文本被设置为常规短的最大值而不是无符号的短… 或沿着这些线的东西 。 我怀疑DataGridViewTextBoxCell()的实现中的PaintPrivate()方法,所以如果你感觉很活泼,可能会把显微镜放在上面。 你需要一个IL反汇编程序才能看到这些没有公开曝光的内容。 具体来说,这部分代码我怀疑:

  if (text != null && (paint && !flag2 || computeContentBounds)) { int y = cellStyle.WrapMode == DataGridViewTriState.True ? 1 : 2; rectangle3.Offset(0, y); // ISSUE: explicit reference operation // ISSUE: variable of a reference type Rectangle& local = @rectangle3; // ISSUE: explicit reference operation int width = (^local).Width; // ISSUE: explicit reference operation (^local).Width = width; rectangle3.Height -= y + 1; if (rectangle3.Width > 0 && rectangle3.Height > 0) { TextFormatFlags cellStyleAlignment = DataGridViewUtilities.ComputeTextFormatFlagsForCellStyleAlignment(this.DataGridView.RightToLeftInternal, cellStyle.Alignment, cellStyle.WrapMode); if (paint) { if (DataGridViewCell.PaintContentForeground(paintParts)) { if ((cellStyleAlignment & TextFormatFlags.SingleLine) != TextFormatFlags.Default) cellStyleAlignment |= TextFormatFlags.EndEllipsis; TextRenderer.DrawText((IDeviceContext) graphics, text, cellStyle.Font, rectangle3, flag3 ? cellStyle.SelectionForeColor : cellStyle.ForeColor, cellStyleAlignment); } } else rectangle1 = DataGridViewUtilities.GetTextBounds(rectangle3, text, cellStyleAlignment, cellStyle); } 

抱歉这本书!

TL;如果您想将字符包含在巨大的细胞中,请使用小屁股。