首页 文章

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

提问于
浏览
5

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

  • Timestamp

  • Connection

  • Message

我发现文本如果太长就会消失的问题 . 具体来说,如果文本的长度超过 4563 个字符,则文本消失 .

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

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

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

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

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

1 回答

  • 6

    这里's the short answer that will probably disappoint you: It'是一个报告的错误并经Microsoft验证,关闭为"Not important enough to fix" . 可能会有更多的实例,但至少从2011年开始就知道DataGridView control shows blank cell if large string is entered and column resized to max . "workaround"只是限制单元格宽度的大小,但对你来说可能并不令人满意 .

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

    enter image description here

    如果你看一下这一系列的图片,你对_ 544这么特别吗?好吧,没有什么特别的,除了当你的角色阈值越过它时,列的ContentBounds和Width传递32767. 32767有什么特别之处?除了作为 DataGridViewTextBoxCell 的默认 MaxInputLength 之外,这个问题恰巧发生在这里,虽然不是因为与 MaxInputLength 本身有任何关系 . 我愿意打赌你首先注意到4563个字符的问题,因为你的字体大小也将宽度扩展到32767 .

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

    enter image description here

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

    具有讽刺意味的是有两个原因 . 例如,使用默认设置,尽管编辑输入长度为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);
        }
    

    Sorry for the book!

    TL;DR USE A SMALL ASS FONT IF YOU WANT TO PACK CHARACTERS INTO HUGE CELLS.

相关问题