C#: How to draw very large controls in a scrollabl

2019-08-14 10:22发布

问题:

Imagine a bar graph with horizontal bars that may be very wide. I have a Panel on a Form where I want to display these bars and scroll and zoom them. The Form, and thus the Panel, can be resized. The bars are dynamically created from a database. Each time the user zooms in or out, all bars have to be created anew to adjust their sizes on the Panel.

I use Label controls to create these bars, but the problem applies to all other controls as well: If I zoom in far enough, my bars will eventually exceed the magic 16 bit border of control sizes (>65536 pixels). This makes it impossible to simply create all the controls on the panel at start and let the panel handle the scrolling.

My idea: Clear the Panel of all bar controls and create only the ones that are visible in the current view window, according to the current position of the scroll bars and the zoom level. The bars exceeding far from the visible view will be cut short just outside the Panel, so their maximum size is limited by the Panel size.

My questions:

  • At which Panel event(s) should this clear/create process take place best? There could be thousands of controls, so it should be as seldom as possible.
  • Is there a better way to handle this? Maybe I got it all wrong from the start.

This problem arises not only with huge controls but also when smaller controls are very far apart (>65536 pixels) on a Panel, so I think a good solution may be helpful for many projects.

回答1:

I wouldn't like to have to create / destroy controls, or hide / resize controls just for their click events. It's quite easy to create a UserControl and override the OnPaint method to draw the bars, and override the OnClick or OnMouseXxx events.

Since you already know the positions of the bars in "virtual space", it's easy to map the location of the mouse cursor to a bar (or a click outside a bar).



回答2:

I know you said winforms is Mandatory, but I really think you should look into the wpf viewbox. You can host a wpf element in winforms. So everything else can be forms related, and you have a panel that hosts and displays your controls. I could write up a quick example that might demonstrate this for you, but if you have no intent of going this way I really don't want to waste my time.



回答3:

You could create a metafile (vector graphics), show that in an image control, and manually determine which logical element is clicked.