Is it possible to trigger a "fake" scroll progmatically in WinForms? - c#

Is it possible to trigger a "fake" scroll progmatically in WinForms?
The scenario:
A form with various drawings on it done with System.Drawing (and no scrollbars).
What I would like:
Progmatically tell the Form the user has scrolled by 10 pixels to the left.
The Form moves the existing drawing 10 pixels to the left.
The Form generates a paint event with a ClipRectangle containing just the right-hand 10 pixels that are now empty.
Is this possible or do I need to handle this myself?

You can add a panel to the form that is larger then the form. Keep the scroll bar turned off and manually scroll the panel by setting the value properties of the VerticalScroll and HorizontalScroll properties of the Panel.
Then add your drawing to the panel instead of the form.
this.panel1.VerticalScroll.Value = 50;
this.panel1.HorizontalScroll.Value = 100;

I honestly have no idea whether that would work, but my guess is that if a scrollbar isn't present on the form it wouldn't.
However, I would expect that if you have a PictureBox control that was sized larger than the client area of the form, and you moved it, it would be updated with only the specific clip region.

You could try putting the drawing whatever it is in a separate container then just moving the location of the container to a location off the main form. .location = -10,0 for example. This will create the illusion that it moved a certain number of pixels off the screen. You can also always fire your own repaint event if the location change does not successfully do this. Other than that you can always owner draw everything.

Since you're using System.Drawing you'll need to tell the drawing methods (OnPaint() or where ever you're drawing) to start drawing at an x offset of -10 pixels. Everything you draw would then be offset by that amount.
Shifting the whole drawing left 10 pixels would be cause to invalidate the whole screen region, not just the 10 pixels on the right of the screen. There are a couple of ways you could do this:
1) Set your offset to -= 10 pixels. Invalidate the whole screen by calling Invalidate(). This would force a redraw of the entire screen and, as long as you have coded your offsets correctly, will redraw everything 10 pixels over.
2) Take an in-memory dump of what's on the screen and make an Image out of it. Then redraw that image 10 pixels to the left off the screen. After that, simply Invalidate the right-most 10 pixels.
Method #2 is, in fact, a lot slower than method #1. Redrawing the screen is quite fast if you don't have millions of things you need to draw.

Related

Autoscroll panel with graphics drawn on it

I have a WinForms app, which has a large panel, which I am drawing on to. Basically, I implemented a scrollbar mechanism, which can imitate a zoom behavior on my drawing. Now I want to do something more.
I thought about adding a possibility to not zoom my drawing if it doesn't fit on the panel, but just use a scroll (vertical or horizontal) to see the full picture. So it looks like this:
Zoom is set to 1: (drawing is too big, there are supposed to be 4 circles)
I zoom back, and there they are, but really, really small:
And I want to have a possibility to just scroll the panel (f.e. in this situation horizontally), to see the whole drawing without having to shrink those drawings.
P.S I searched through SO, and I only found answers suggesting using PictureBox instead of Panel and I'm not sure I want to do that

Form resize and image size syncing

I'm busy implementing some image resizing operations. The gist of it is for every 1 pixel the form resizes, the image will resize by 1 pixel. For now, I have only implemented width reduction. I have an overridden Panel that I use to paint my image in OnPaint method.
I am listening to the From.Resize and I'm doing the width reduction in there. When that is done, I call Invalidate on my custom Panel which redraws the image. This all works.
As you can imagine the form resizes quicker than what my image reduction code runs and that is fine. If I take my time and resize slowly, then the Form size and image size stay in sync but if I do a "hard" resize, the Form quickly becomes smaller than the image. It seems resizing does not block UI thread.
Is there some way I can "block" or slow down the resizing so the two can stay in sync width wise?

Keep form and controls proportion deployng a c# application for any screen size

I know this is an "already heard" problem: I have searched a lot but I did not find anything that cleared my mind.
I am developing a c# application with a GUI containing some controls like buttons (made with images) and text.
I developed it setting the main form size to 800x600 but now I need the application to work also on a 1920x1080 screen.
Two problems:
If I position a button near the top-right corner of the main form and set AnchorStyles to Top-Right, when I switch to the big screen, the button is (in proportion) much more close to top-left corner than in the little screen (because the anchor keeps the distance from the border). Is there a way to set a proportional distance from the border?
How can I scale the dimensions of the controls proportionally to the screen size? Shall I use AutoScaleMode like suggested here?
There is a way to add a capability to a form at design time - the ToolTip control does it, that makes properties available to every control on a form. These are called "Extender Providers"
http://msdn.microsoft.com/en-us/library/ms171836
You would want to look at the controls, and cache their sizes and fonts at design time, and the size of the form.
The provider would hang off the form.SizeChanged event at run time. When the size changes, you use the new and original (design time) sizes of the form to calculate and X and Y ratio. You then go through each control and use it's design time size and the ratios to determine its new size and font size. This can get flaky if you allow the user to select sizes that are not the same aspect ratio as your original.
Anyway, that is how it was done in Delphi, and everyone knows if you can do it in Delphi, you can do it in C# :)

auto-scaling size with anchors - overlapping controls

I'm having some trouble with resizing and scaling of controls in a windows form. I've set anchors up so that the controls stay in ratio with the form, which works great. However, perhaps i was expecting too much when i thought that the control origin points would also scale and change with the form scaling, but this is not the case and i'm finding my controls overlapping. here's some screenshots;
anyone know of an approach i can take to solve this problem? perhaps i need to set control origins to dynamic drawing points that scale, but then do these redraw on scaling the form, or only on creation?
edit 1: just found this question hidden amongst the internet, Problem: Anchored controls are overlapping perhaps i need to implement something like this, a resize event.
The preferred solution should be the TableLayoutPanel. Handling OnResize is going to be much more fragile.
I wonder if Anchor is really about scaling, it basically anchors the sides of a control to the container and scaling is a by product of this. For eg. if both left & right sides are anchored the control will scale in width because anchor will try to keep the location of left & right sides intact.
keeping that in mind you have to think what do you want when the form is increased in size and you have more space. In the case above you might want the list box lbLog to say remain same size but the panel Simulate take up any sapce created. For such a scenario you would anchor the panel on both left & Right side while you will anchor the list box only the right.
Basically if you want all your controls to proportionally scale (true scaling I would say as opposed to scaling in case of anchoring) then Anchoring is not the right solution.

Moving a picturebox with a timer

I'm trying to move a picturebox in a containing control by changing its Top and Left properties every 20ms. On a black background it's a bit smoother but when assigning a BackgroundImage to the control, the picturebox leaves a trail behind it until the control is redrawn a few seconds later, slows down abruptly then launches forward, or moves in a jagged trajectory.
I think when the PictureBox control is redrawn, the thread that changes its left and top properties is halted until redrawn is complete and that causes it to queue up any iterations of the timer loop that were held up, when the redraw is complete.
Is there anyway to smoothen up the picturebox's movement?
Thanks
F
I'd suggest drawing an image in one control as opposed to moving around controls.
Create a custom control, override OnPaint and draw your "picture box" inside there. If you do this you can also back buffer. Do this by calling Graphics.FromImage() to create a graphics object from an image. Paint onto that and finally call g.DrawImage on the REAL graphics object (in the eventArgs) once you're done drawing.
I don't know exactly how to resolve the problem (other than switching to WPF) but I can say the lag you're getting is coming from the invalidation of the areas that are being updated as you move the PictureBox. What you want to do is somehow back-buffer the new position and switch to the buffer, rather than relying on GDI to do the redraw in realtime. HTH.

Categories