如何在面板中创建一个包含FillRectangle的滚动条? [英] How do I create a scrollbar in panel which contain a FillRectangle inside?

查看:107
本文介绍了如何在面板中创建一个包含FillRectangle的滚动条?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Form中创建了2个面板,其中Panel1设置为Auto Scroll。 Panel2位于Panel1内,并包含一个Fill Rectangle,它使用Timer设置,因此它看起来像一个进度条。问题是,当我将Panel1向右滚动时,是..它向右滚动但当我向左滚动时,左侧的颜色恢复为其默认颜色的正常别名。那么当我向右滚动时,如何在左侧保留这种颜色?



任何回复,谢谢:)

I already create 2 panel in Form, which Panel1 is set to Auto Scroll. Panel2 is inside Panel1 and contain a Fill Rectangle which is set with Timer so it looks like a progress bar. The problem is, when i scroll Panel1 to right, yes.. it scrolled to right but when I scroll it back to left, the color in left side is back to normal alias to its default color. Then how to preserve this color on the left side when I scroll it to right?

Any response, Thanks :)

'This code is inside Form1_Load
Grafik = Panel2.CreateGraphics
Timer1.Start()

'This code is inside Timer1_Tick
time += 10
If time <= 100 Then
Grafik.FillRectangle(Brushes.BlueViolet, 0, 0, time, 25)
ElseIf time <= 200 Then
Grafik.FillRectangle(Brushes.Brown, 100, 0, time - 100, 25)
ElseIf time <= 300 Then
Grafik.FillRectangle(Brushes.DarkOrange, 200, 0, time - 200, 25)
ElseIf time <= 400 Then
Grafik.FillRectangle(Brushes.DarkSalmon, 300, 0, time - 300, 25)
ElseIf time <= 500 Then
Grafik.FillRectangle(Brushes.DarkSlateGray, 400, 0, time - 400, 25)
End If





http://s15.postimg.org/ix9q15rzv/cap.png [ ^ ]



当它向右滚动然后向后滚动时,它应该是紫色的颜色,但它默认为灰色..



http://s15.postimg.org/ix9q15rzv/cap.png[^]

When it scroll to right then scroll back to left, it should be violet color, but it is default like gray..

推荐答案

你不能包含一个FillRectangle;这不是一个静止的物体。您可以使用 System.Drawing.Graphics.FillRectangle 渲染矩形,但它会响应 Paint 事件而发生。 />


首先,滚动。对于滚动,您可以控制在一些可滚动控件内部渲染图形的位置,例如 Panel ,并滚动该面板。 面板 ScrollableControl ,所以请看:

https://msdn.microsoft.com/en-us/library/system。 windows.forms.scrollablecontrol%28v = vs.110%29.aspx [ ^ ]。



内部控制应该呈现你的内容希望通过重写 OnPaint 方法或处理 Paint 事件(然后你也可以使用 Panel ,但 OnPaint 将需要派生类)。但是你的图形不是静态的,它是动画的,或者是以任何方式改变的。



这个想法是:你需要有一些数据模型描述您的图形,在您的情况下,描述当前矩形颜色/大小/位置的一些数据集。你的渲染方法不应该使用常量值(使用硬编码的立即常量无论如何都是糟糕的样式,无论如何都非常不利于项目的维护),但是来自模型的值。如果更改值并调用 Invalidate 方法,它将触发重新绘制无效控件中的图形。你需要了解它是如何工作的。请查看我过去的答案:

什么样的俏皮方法是Paint? (DataGridViewImageCell.Paint(...)) [ ^ ],

在面板上捕获绘图 [ ^ ],

mdi子表单之间的绘制线 [ ^ ],

C#.net鼠标滚轮中的缩放图像 [ ^ ]。



然后你可以创建一个单独的线程来实现动画序列的场景。它可以是任何东西,例如渲染某些游戏的物理。单独的方案比定时器更容易实现,因为它是顺序的,逻辑上独立于您的UI。您不希望拥有定时器的特定问题。我不想浪费更多时间来解释;只是不要使用计时器。我过去的答案解释了这样的动画:

如何加速我的vb.net应用程序? [ ^ ]。



您的线程只更改数据,并通过调用 Control.Invalidate 重新绘制触发器。但你不能直接在非UI线程中调用这个方法(同样适用于计时器,不包括计时器 System.Windows.Forms.Timer 这完全不适合动画,因为它的准确度太高了)。我在上面提到的答案中也对此进行了解释。您需要使用 Control.Invoke Control.Invalidate 委托给UI线程。另见我过去的答案:

问题Treeview扫描仪和MD5 [ ^ ],

Control.Invoke()与Control.BeginInvoke() [ ^ ]。



就是这样。



-SA
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


问题是您只在Panel上绘制一次。滚动面板后,您绘制的所有内容都将丢失。您必须在Panels Paint事件中绘制Panel。每次滚动面板或在面板上传递另一个窗口时,您将丢失所有绘制的内容并且必须重新绘制它。 Windows将通过提高Panels Paint事件来告诉您何时需要重新绘制。
You problem is that you paint on the Panel only once. Once you scroll the Panel over, everything you painted is lost. You have to do the painting of the Panel in the Panels Paint event. Every time the Panel is scrolled or another window is passed over your panel you will lose everything you painted and have to repaint it. Windows will tell you when you have to repaint by raising your Panels Paint event.


我完全不了解您想要做什么......但我会做以下事情:



您创建自己的控件。

此控件继承自Panel(如果您愿意 - 我会接受控制)。

在此控件中集成了Timer。

在此控件中,您将覆盖OnPaint方法。这个方法为你提供了一个FillRectangle的图形对象,并且你的控件每次失效都会重新调用这个方法。

用你的Timer强制你的控件无效。



我希望,这可以帮助你 - 否则回复...
I don't understand completly what you want to do ... but I would do the following :

You create your own Control.
This Control inherits from Panel (if you wish - I would take Control).
Inside this Control you integrate the Timer.
Inside this Control you override the OnPaint-method. This method gives you a Graphics-Object for the FillRectangle and also this method is re-called by each invalidating of your control.
With your Timer you force an Invalidate for your control.

I hope, this helps you - else response ...


这篇关于如何在面板中创建一个包含FillRectangle的滚动条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆