【问题标题】:Panel size limitation - workaround面板尺寸限制 - 解决方法
【发布时间】:2019-07-27 22:46:01
【问题描述】:

我有一个用 Java 制作的小应用程序,我也想用 C# 构建它。但我遇到了面板尺寸限制。
我通过读取一个文件并在该文件中的每一行中在我的持有人面板中实例化一个新对象,将一些自定义面板作为记录添加到表单的持有人面板中。

在 Java 中,您可以在 JPanel 中添加任意数量的对象,因为它使用 JScrollPane 调整大小并查看其中的所有对象。无论如何,我有一个包含 1554 记录的文件,我的 Java 应用程序将显示所有对象,但在 C# 中,由于大小限制,它只显示 738 记录。

我尝试将面板“b”添加到该支架面板,并在该面板 b 中添加所有记录(自定义面板),并将其高度设置为 Int32.MaxValue
我已将BorderStyle 设置为FixedSingle 以便能够查看面板b 的大小。它允许我滚动超过Int16.MaxValue,但我的对象只显示到Int16.MaxValue 值。

唯一的解决方案是对所有记录进行分页?

【问题讨论】:

  • 您在面板中实例化了什么“新对象”?您能否展示一个演示该问题的小代码示例?也不清楚“大小限制”是什么意思。您是否遇到异常或其他运行时错误?您还提到了Int32.MaxValueInt16.MaxValue,两者都远远超过1554。
  • 也许您在另一个平台上使用了一个面板,并且它起作用了。这并不意味着您必须/应该在另一个完全不相关的工具中使用相同的工具(除了语言look)。您有 ListView 或 DataGridView 控件。由于您有一个包含 1554 条记录的文件,您可能会发现这些其他工具更合适。可能的话,用 UI 术语解释这些记录应该翻译成什么。
  • 请参阅here 了解所有 winforms 控件的大小限制! - 我建议使用 FlowLayoutPanel。
  • 这是一个带有自定义渲染 (OwnerDrawn) 的 ListView,在 .Net 术语中。你会发现它比一堆面板更容易处理(也是内存方面的)。

标签: c# winforms panel


【解决方案1】:

将 ListView 设置为您展示的控件并不难。
您只需要自己绘制其项目的某些部分。

设置:
1.ListView.OwnerDraw= true
2.ListView.View= View.Details
3.添加一个Column,ListView的大小减去ScrollBar的大小(SystemInformation.VerticalScrollBarWidth)
4. ListView.HeaderStyle= none 如果您不想显示标题。
5.订阅ListView.DrawSubItem事件
6. 添加ImageList,将其ImageSize.Height设置为ListView的Items的高度,并选择ListView.StateImageList(这样就不需要创建自定义控件了定义项目的高度)。

在这里,我添加了一个实用程序,它根据项目文本的当前对齐方式选择文本格式样式。如果仅将文本左对齐,则没有必要。

如果您有很长的项目列表要添加到 ListView,则可以使用VirtualMode

它和你展示的没有什么不同,对吧?

Color lvPanelsItemCurrentBackColor = Color.FromArgb(58, 188, 58);
Color lvPanelsItemSelectedBackColor = Color.FromArgb(48, 48, 48);
Color lvPanelsItemBackColor = Color.FromArgb(28,28,28);
Color lvPanelsItemForeColor = Color.White;

private void lvPanels_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    var lView = sender as ListView;
    TextFormatFlags flags = GetTextAlignment(lView, e.ColumnIndex);
    Color itemBackColor = lvPanelsItemBackColor;
    Rectangle itemRect = e.Bounds;
    itemRect.Inflate(-2, -2);

    if (e.Item.Selected || e.Item.Focused) {
        itemBackColor = e.Item.Focused ? lvPanelsItemCurrentBackColor : lvPanelsItemSelectedBackColor;
    }
    using (SolidBrush bkgrBrush = new SolidBrush(itemBackColor)) {
        e.Graphics.FillRectangle(bkgrBrush, itemRect);
    }
    TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, e.Bounds, lvPanelsItemForeColor, flags);
}

private TextFormatFlags GetTextAlignment(ListView lstView, int colIndex)
{
    TextFormatFlags flags = (lstView.View == View.Tile)
        ? (colIndex == 0) ? TextFormatFlags.Default : TextFormatFlags.Bottom
        : TextFormatFlags.VerticalCenter;

    flags |= TextFormatFlags.LeftAndRightPadding | TextFormatFlags.NoPrefix;
    switch (lstView.Columns[colIndex].TextAlign)
    {
        case HorizontalAlignment.Left:
            flags |= TextFormatFlags.Left;
            break;
        case HorizontalAlignment.Right:
            flags |= TextFormatFlags.Right;
            break;
        case HorizontalAlignment.Center:
            flags |= TextFormatFlags.HorizontalCenter;
            break;
    }
    return flags;
}

【讨论】:

  • 不,确实,它和我的控件很像,但我看到一个小滚动条,这意味着你只添加了少量项目。而且它在 MouseEnter 和 MouseLeave 的背景色方面存在一些问题。 :) 但我认为它也可以解决。感谢您编辑我的初始帖子。最好的问候!
  • 是的,在这个例子中元素很少,但它可以容纳很多很多。如果项目太多(UI 失去响应),您可以切换到虚拟模式,仅显示总数量的一小部分。如果您指的是渲染,此处不使用 MouseEnter、MouseLeave 事件。所有都在DrawSubItem 处理程序中处理。可以为特定功能添加其他事件。不适合画画。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多