0

I have a little application made in Java and I want to build it in C# too. But I encounter a panel size limitation.
I add some custom Panel as records in a holder panel on a Form, by reading a file and for each line in that file I instantiate a new object in my holder Panel.

In Java you can add as many objects you want in a JPanel, as it resize and view all the objects inside it, using a JScrollPane. Anyway, I have a file with 1554 records inside and my Java application it will show all the objects, but in C# it shows me only 738 records, because of size limitation.

I have tried to add a panel "b" to that holder panel, and to add all the records (custom panel) in that panel b, and setting its height as Int32.MaxValue.
I have set the BorderStyle to FixedSingle to be able to view the size of panel b. It allows me to scroll more than Int16.MaxValue, but my objects are shown only till that Int16.MaxValue value.

The only solution is by paging all records?

JPanel with JScrollPane

Jimi
  • 29,621
  • 8
  • 43
  • 61
Vali Maties
  • 379
  • 1
  • 2
  • 21
  • What "new object" are you instantiating inside the panel? Can you please show a small code sample that demonstrates the problem? It's not clear what you mean by "size limitation" either. Are you getting an exception or other runtime error? You also mention `Int32.MaxValue` and `Int16.MaxValue`, both of which are well over 1554. – Rufus L Jul 26 '19 at 23:04
  • Maybe you used a panel, in another platform, and it worked. It doesn't mean you have to/should use the same tool in another one, totally unrelated (except the language *look*). You have the ListView or DataGridView controls. Since you have *a file with 1554 records*, you may find these other tools a better fit. Possibly, explain what these *records* should translate to in UI terms. – Jimi Jul 27 '19 at 05:51
  • See [here](https://stackoverflow.com/questions/25709069/the-maximum-number-of-characters-a-textbox-can-display/25709337?r=SearchResults&s=1|41.4716#25709337) about size limits of all winforms controls ! - I suggest using a FlowLayoutPanel. – TaW Jul 27 '19 at 07:33
  • Look here: http://www.mediafire.com/view/y6vcl2z174a4bts/PanelHeight.jpg# – Vali Maties Jul 27 '19 at 09:39
  • 1
    That's a ListView with custom rendering (OwnerDrawn), in .Net terms. You'ld find it much easier to handle than a bunch of Panels (also memory-wise). – Jimi Jul 27 '19 at 09:47
  • Sample code and process description here: [How to change default selection color of a ListView?](https://stackoverflow.com/a/55525989/7444103). – Jimi Jul 27 '19 at 10:03
  • Thanks Jimi. I will try to move to ListView. – Vali Maties Jul 27 '19 at 10:19
  • I have tried using ListView, but is very difficult to achieve the look I made as in my picture above. It is difficult to change row height, and I searched for a solution to insert row lines (as gaps in my picture above) which I did not find one. So I think I will have to search more for another way of doing this. I will go for a look to FlowLayoutPanel ... – Vali Maties Jul 27 '19 at 11:42
  • FlowLayoutPanel, the same behaviour as Panel. Remains DataGridView.. – Vali Maties Jul 27 '19 at 12:23
  • _FlowLayoutPanel, the same behaviour as Panel._ Meaning what? It will easily accomodate thousands of records but only with scrollbars, not with a huge height. – TaW Jul 27 '19 at 13:31
  • That's the problem @TaW, I want to use it with huge height. Even with scrollbar activated its shows only some of the records, depends on height of the record. The record, as it is explained in my post is a custom panel having some labels in it. So if DataGridView is the way and if I will be able to format DataGridView as it shows in picture above, I will use DataGridView insteed. Thanks. – Vali Maties Jul 27 '19 at 13:56
  • If you follow the link you will learn that there is a 16k pixel limit to all winforms controls. __All__ includes FLP, DGV etc..I don't understand what issue you have with scrollbars. – TaW Jul 27 '19 at 14:01

1 Answers1

0

It's not difficult to setup a ListView as the Control you showed.
You just need to paint some parts of its Items yourself.

Set:
1. ListView.OwnerDraw= true
2. ListView.View= View.Details
3. Add one Column, the size of the ListView minus the size of the ScrollBar (SystemInformation.VerticalScrollBarWidth)
4. ListView.HeaderStyle= none if you don't want to show the header.
5. Subscribe to the ListView.DrawSubItem event
6. Add an ImageList, set its ImageSize.Height to the height of the Items of your ListView and select it as the ListView.StateImageList (so it won't be necessary to create a Custom Control to define the Items' height).

Here I've added an utility that selects the Text formatting style based on the current alignment of the Items' Text. It won't be necessary if you align the Text to the left only.

In case you have a very long list of Items to add to the ListView, a VirtualMode is available.

It's not that different from the one you've shown, right?.

ListView OwnerDraw

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;
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
  • No, indeed, it is mostly like my control, but I see a small scrollbar, which means you have added only a small amount of items. And it has some problems with MouseEnter and MouseLeave backcolor. :) But I think shurelly it can be solved, too.. Thanks for editing my initial post. Best regards! – Vali Maties Jul 27 '19 at 16:57
  • Yes, in the example the elements are few, but it can hold many, many more. If the items are too many (the UI loses responsiveness), you can switch to virtual mode, showing only a fraction of the total amout. The MouseEnter, MouseLeave events are not used here, if you're referring to the rendering. All is handled in the `DrawSubItem` handler. Other events can be added for specific functionality. Not for drawing. – Jimi Jul 27 '19 at 17:02