You cannot "contain a FillRectangle"; this is not a stationary object. You can render rectangle using
System.Drawing.Graphics.FillRectangle
, but it happens in response to
Paint
event.
First, scrolling. For scrolling, you can have your control where you render graphics inside some scrollable control, such as
Panel
, and scroll that panel.
Panel
is
ScrollableControl
, so please see:
https://msdn.microsoft.com/en-us/library/system.windows.forms.scrollablecontrol%28v=vs.110%29.aspx[
^].
Inner control should render what you want by overriding
OnPaint
method or handling the
Paint
event (then you could also use
Panel
, but
OnPaint
would require a derived class). But your graphics is not static, it is animated, or is changed in any way.
The idea is: you need to have some
data model which describe your graphics, in your case, some data set describing current rectangle color/size/location. You rendering method should not use constant values (using hard-coded
immediate constants is bad style anyway, really bad for maintenance of your project anyway), but values from the model. If you change the values and call
Invalidate
method, it will trigger re-drawing the graphics in the invalidated control. You need to understand how it works. Please see my past answers:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[
^],
capture the drawing on a panel[
^],
Drawing Lines between mdi child forms[
^],
Zoom image in C# .net mouse wheel[
^].
Then you can create a separate thread which implements the scenario of the animated sequence. It could be anything, such as rendering "physics" of some game. The scenario in a separate tread is much easier to implement than timers, because it is sequential, logically independent from your UI. There are specific problems with timers you don't want to have. I don't want to waste more time for explanation; just don't use timers. My past answer explains such animation:
How to speed up my vb.net application?[
^].
Your thread only changes the data, and the triggers re-drawing by calling
Control.Invalidate
. But you cannot call this method directly in a non UI thread (the same goes for timers, excluding the timer
System.Windows.Forms.Timer
which is totally unsuitable for animation due to its prohibitively bad accuracy). It is also explained in my past answer referenced above. You need to use
Control.Invoke
to delegate the
Control.Invalidate
call to the UI thread. See also my past answers:
Problem with Treeview Scanner And MD5[
^],
Control.Invoke() vs. Control.BeginInvoke()[
^].
That's all.
—SA