Мерцание(flickering) У кого мерцает читать обязательно

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Мерцание(flickering) У кого мерцает читать обязательно

Сообщение percilacus » 28.08.2009 (Пт) 19:36

Окончание. Начало http://bbs.vbstreets.ru/viewtopic.php?f=2&t=40515
Перед тем как читать дальше рекомендуется прочитать начало

Я избавился от мерцания.
Вот код:
Код: Выделить всё
Imports System.Drawing.Drawing2D
Public Class Form1
    Private pen1 As New Pen(Color.Blue, 20)
    Private grpath_col As New Collection
    Private grpath As New GraphicsPath
    Private temp_grpath As GraphicsPath
    Private last_point As New PointF(Single.NaN, Single.NaN)
    Private currentContext As BufferedGraphicsContext = BufferedGraphicsManager.Current
    Private buffer As BufferedGraphics
    Private Delegate Sub WhatDraw()
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.BackColor = SystemColors.Control
        pen1.MiterLimit = 1.5
    End Sub
    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        Select Case e.Button
            Case Windows.Forms.MouseButtons.Left
                If Not Single.IsNaN(last_point.X) Then
                    grpath.AddLine(last_point, New PointF(e.X, e.Y))
                End If
                last_point = New PointF(e.X, e.Y)
            Case Windows.Forms.MouseButtons.Right
                If grpath.PointCount <> 0 Then grpath_col.Add(grpath)
                grpath = New GraphicsPath
                last_point = New PointF(Single.NaN, Single.NaN)
                DrawToBuffer(AddressOf DrawAllPath)
        End Select
    End Sub
    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If Not Single.IsNaN(last_point.X) Then
            temp_grpath = grpath.Clone
            temp_grpath.AddLine(last_point, e.Location)
            DrawToBuffer(AddressOf DrawAllPath, AddressOf DrawTempPath)
        End If
    End Sub
    Private Sub DrawAllPath()
        For Each obj As GraphicsPath In grpath_col
            buffer.Graphics.DrawPath(pen1, obj)
        Next
    End Sub
    Private Sub DrawTempPath()
        buffer.Graphics.DrawPath(pen1, temp_grpath)
    End Sub
    Private Sub DrawToBuffer(ByVal ParamArray drawsmth() As WhatDraw)
        buffer = currentContext.Allocate(Me.CreateGraphics, Me.ClientRectangle)
        buffer.Graphics.FillRectangle(New SolidBrush(SystemColors.Control), Me.DisplayRectangle) 'подложка цвета фона
        For i As Integer = 0 To UBound(drawsmth)
            drawsmth(i)()
        Next
        buffer.Render()
    End Sub
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        DrawToBuffer(AddressOf DrawAllPath)
    End Sub
End Class


Как видно не мерцает совсем.
Решение заключается в использовании т.н. буфера - экземпляра класса BufferedGraphics. Но он не используется сам по себе, а чаще в связке с классами BufferedGraphicsContext и BufferedGraphicsManager. Подробнее можно прочитать в MSDN :mrgreen:
перцилакус такой маленький а уже знает что такое хорошо а что такое плохо

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Мерцание(flickering) У кого мерцает читать обязательно

Сообщение Nord777 » 29.08.2009 (Сб) 1:40

Окончание. Начало viewtopic.php?f=2&t=40515
Перед тем как читать дальше рекомендуется прочитать начало
Перед тем, как изобретать велосипед, тебе самому надо было внимательно прочитать, что тебе советовали. :wink:

Код: Выделить всё
Imports System.Drawing.Drawing2D
Public Class Form1
   Dim pen1 As New Pen(Color.Blue, 20) With {.MiterLimit = 1.5!, .LineJoin = LineJoin.Round}
   Dim GP As New GraphicsPath
   Dim pnt As New List(Of Point)
   Dim Drawing As Boolean
   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      Me.DoubleBuffered = True
   End Sub
   Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
      Select Case e.Button
         Case Windows.Forms.MouseButtons.Left
            pnt.Add(New Point(e.X, e.Y))
            If Not Drawing Then pnt.Add(New Point(e.X + 1, e.Y + 1))
            Drawing = True
         Case Windows.Forms.MouseButtons.Right
            pnt.RemoveAt(pnt.Count - 1)
            GP.StartFigure() : GP.AddLines(pnt.ToArray)
            pnt.Clear() : Invalidate()
            Drawing = False
      End Select
   End Sub
   Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
      If Not Drawing OrElse pnt.Count = 0 Then Exit Sub
      pnt(pnt.Count - 1) = New Point(e.X, e.Y)
      Invalidate()
   End Sub
   Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
      e.Graphics.SmoothingMode = SmoothingMode.HighQuality
      If GP IsNot Nothing Then e.Graphics.DrawPath(pen1, GP)
      If pnt.Count > 0 Then e.Graphics.DrawLines(pen1, pnt.ToArray)
   End Sub
End Class
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Re: Мерцание(flickering) У кого мерцает читать обязательно

Сообщение percilacus » 29.08.2009 (Сб) 18:40

Да, так лучше.
Спасибо!
Интересно, что если в событии Paint использовать не e.Graphics, а модульную переменную, например, объявленную так
Private Gr As Graphics=Me.Creategraphics(), то ничего не будет работать. Я раньше так и делал и удивлялся почему делаю двойную буферизацию а все равно мерцает

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Мерцание(flickering) У кого мерцает читать обязательно

Сообщение FireFenix » 02.09.2009 (Ср) 16:07

А как убрать мерцание в ListView?

заполняю/изменяю произвольные элементы в ListView и при добавлении/измении каждой записи происходит полная отрисовка контрола
пробывал двойную буферизацию - не спасает

где-то было, что нужно использовать обёртку для листвиев... но тоже ничего не вышло...
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Мерцание(flickering) У кого мерцает читать обязательно

Сообщение Nord777 » 02.09.2009 (Ср) 16:10

пробывал двойную буферизацию - не спасает
Не верю. Покажи.
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Мерцание(flickering) У кого мерцает читать обязательно

Сообщение FireFenix » 05.09.2009 (Сб) 14:31

Nord777 писал(а):
пробывал двойную буферизацию - не спасает
Не верю. Покажи.

Ууупс... раньше мучался и забил.... щас наследовал листвиев и сделал буферизацию - получилось с первого раза... Мистика! :D

Код: Выделить всё
Me.lv_List = New ListViewModifed

Код: Выделить всё
Class ListViewModifed : Inherits ListView
    Public Sub New()
        Me.DoubleBuffered = True
    End Sub
End Class
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 76

    TopList  
cron