我需要一种避免在面板上闪烁的方法,我在这里提出了很多类似的问题,并且在世界各地试图向专家询问,我尝试过很多技巧,扩展面板,创建框架,控制方式,浪费了很多时间,浪费时间学习那些不起作用的东西......我在这一点上陷入困境。
...没有什么能像预期的那样真正起作用,我找到的最好的“闪烁减速器”是“Createparams”覆盖子,但是这种方法使任何Form / App的任何操作速度都慢了x20倍,I如果这意味着应用程序性能下降,则不要松散闪烁(至少如果与CreateParams的性能相同,则不会这样。)
在这个视频中你可以看到我的测试表格有一个50%透明的面板,其中里面有图片框,背景图像设置为“缩放”分层,当我向上或向下滚动时,我得到了很多闪烁。
http://www.youtube.com/watch?v=zIBDTMjrDd4&feature=youtu.be
我使用“CreateParams”方法,如果我不使用“CreateParams”,你真的不会看到我的面板闪烁会发生什么,真的很可怕。
这是没有闪烁时的面板:
这是小组片刻,它闪烁着:
这是完整的课程:
It is a Windows Form proyect
VS2012
Framework 3.5
On Windows 7 x64
Application Visual Styles is ON
Double Buffer is ON
Panel and pictureboxes are default controls
(我认为没必要说我已经尝试了所有可能的视觉和环境配置,人们说我永远忘记了闪烁。)
Public Class Form1
Dim Scroll_Position As Int32 = 0
Dim Button_Down_Is_Pressed As Boolean = False
Dim Button_Up_Is_Pressed As Boolean = False
Dim WithEvents Progressive_Scroll_Timer As New Timer
Dim SmallChange As Int32 = 5
Dim Largechange As Int32 = 10
' Sub which reduces the Flickering, but this sub makes x20 times slower any operation of any Form/Application.
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property 'CreateParams
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Me.BackColor = Color.FromArgb(255, 0, 0, 0)
' Me.TransparencyKey = Color.FromArgb(255, 0, 0, 0)
Panel1.VerticalScroll.Maximum = 999999999
Progressive_Scroll_Timer.Interval = 50
Panel1.BackColor = Color.FromArgb(150, 0, 0, 0)
End Sub
Private Sub Panel_MouseHover(sender As Object, e As EventArgs) Handles Panel1.MouseHover
sender.focus()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Progressive_Scroll_Timer.Tick
If Button_Down_Is_Pressed Then
Scroll_Down(SmallChange)
ElseIf Button_Up_Is_Pressed Then
Scroll_Up(SmallChange)
Else
sender.stop()
End If
End Sub
Private Sub Scroll_Up(ByVal Change As Int32)
Scroll_Position -= Change
Panel1.SuspendLayout()
Try : Panel1.VerticalScroll.Value = Scroll_Position : Catch : Scroll_Position += Change : End Try
Panel1.ResumeLayout()
End Sub
Private Sub Scroll_Down(ByVal Change As Int32)
Scroll_Position += Change
Try : Panel1.VerticalScroll.Value = Scroll_Position : Catch : Scroll_Position -= Change : End Try
End Sub
Private Sub Button_Down_MouseDown(sender As Object, e As MouseEventArgs) Handles Button2.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Button_Down_Is_Pressed = True
Progressive_Scroll_Timer.Start()
End If
End Sub
Private Sub Button_Up_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Button_Up_Is_Pressed = True
Progressive_Scroll_Timer.Start()
End If
End Sub
Private Sub Button_Down_MouseUp(sender As Object, e As MouseEventArgs) Handles Button2.MouseUp
Button_Down_Is_Pressed = False
End Sub
Private Sub Button_Up_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUp
Button_Up_Is_Pressed = False
End Sub
Private Sub Form_MouseWheel(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Panel1.MouseWheel
If Panel1.Focused Then
Select Case Math.Sign(e.Delta)
Case Is > 0 : Scroll_Up(Largechange)
Case Is < 0 : Scroll_Down(Largechange)
End Select
End If
End Sub
End Class
答案 0 :(得分:5)
将Panel
&#39; AutoScroll
属性设置为true
。如果没有这个,滚动似乎不起作用。
添加从DoubleBufferedPanel
类继承的Panel
类,并将.DoubleBuffered
属性设置为true:
Public Class DoubleBufferedPanel
Inherits Panel
Public Sub New()
DoubleBuffered = True
End Sub
End Class
现在转到隐藏的InitializeComponent
子(右键单击Panel1
变量,然后点击Go To Definition
)。在需要的地方(两个地方)将Panel
类型替换为DoubleBufferedPanel
:
Me.Panel1 = New WindowsApplication4.DoubleBufferedPanel()
....
Friend WithEvents Panel1 As WindowsApplication4.DoubleBufferedPanel
闪烁应该停止(尽管还有一些其他效果)。
删除CreateParams
以提高速度。
P.S。总的来说,这不是一个好主意(移动复杂的半透明图像)。为什么不使用像ListView
这样的东西?为什么不在不使用Panel
的情况下自行移动图像?如果您想获得最佳速度,只需使用.BackgroundImage
和Bitmap
类在表单(Graphics
)上绘制图片。
P.P.S。使用Panel
以编程方式滚动.AutoScroll = true
似乎存在一些严重错误。我不得不重新分配滚动值以防止严重的抖动。我已将案件隔离,并将向Microsoft提交错误报告。
答案 1 :(得分:3)
使用代表class
及其内容的复杂panel
,然后绘制(GDI+
)到Picturebox
上的内容可以很好地渲染。我做过几个这样的项目。
答案 2 :(得分:3)
您可以将表单的DoubleBuffered
属性设置为True
修改:
我认为你不需要Timer。 所以,你修改过的代码有点像这样:
Public Class Form1
Dim Scroll_Position As Int32 = 0
Dim SmallChange As Int32 = 5
Dim Largechange As Int32 = 10
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Me.BackColor = Color.FromArgb(255, 0, 0, 0)
' Me.TransparencyKey = Color.FromArgb(255, 0, 0, 0)
Panel1.VerticalScroll.Maximum = 999999999
Panel1.BackColor = Color.FromArgb(150, 0, 0, 0)
End Sub
Private Sub Panel_MouseHover(sender As Object, e As EventArgs) Handles Panel1.MouseHover
sender.focus()
End Sub
Private Sub Scroll_Up(ByVal Change As Int32)
Try
Scroll_Position -= Change
Panel1.VerticalScroll.Value = Scroll_Position
End Try
End Sub
Private Sub Scroll_Down(ByVal Change As Int32)
Try
Scroll_Position += Change
Panel1.VerticalScroll.Value = Scroll_Position
End Try
End Sub
Private Sub Button_Down_MouseDown(sender As Object, e As MouseEventArgs) Handles Button2.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
scrollDown(smallChange)
End If
End Sub
Private Sub Button_Up_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
scrollUp(SmallChange)
End If
End Sub
Private Sub Form_MouseWheel(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Panel1.MouseWheel
If Panel1.Focused Then
Select Case Math.Sign(e.Delta)
Case Is > 0 : Scroll_Up(Largechange)
Case Is < 0 : Scroll_Down(Largechange)
End Select
End If
End Sub
End Class
这可能不是解决方案,但这是我方的努力。
答案 3 :(得分:1)
将其放入表单加载
' to remove flick
Dim aProp As PropertyInfo = GetType(Panel).GetProperty("DoubleBuffered", BindingFlags.NonPublic Or BindingFlags.Instance)
aProp.SetValue(Panel7, True, Nothing)
将Panel7替换为带有背景图像的控件名称。