[英]TabControl flickering when changing the tab's icon
我要在這里失去理智。 我一直在谷歌搜索一小時試圖解決這個小問題,但令人難以置信的加重問題。
我的表單上有一個帶有兩個選項卡的TabControl
。 每個選項卡都有一個16x16圖標和一些文本。 這里沒什么可瘋狂的。
在某些情況下,我需要讓其中一個標簽圖標閃爍。 所以我創建了兩個圖像, 和
並將它們添加到
TabControl
使用的ImageList
。 我設置了一個后台計時器,可以在兩個圖像之間切換以模擬閃爍的圖標。 工作良好。
但是,它導致所有標簽標題重繪,這使它們閃爍。
無論您嘗試做什么, TabControl
都不支持雙緩沖。
我發現人們使用這段代碼有一些成功馴服閃爍:
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
這有效,因為它不會閃爍......但除非鼠標光標懸停在導致重繪的內容之上,否則圖標也不會在視覺上發生變化。
有沒有人有任何可行的替代解決方案或技巧? 這實際上是該軟件非常重要的功能。
骨架代碼:
Public Class Form1
Dim BlinkTimer As Windows.Forms.Timer
Dim BlinkToggler As Boolean = False
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
InitBlinker()
End Sub
Private Sub InitBlinker()
BlinkTimer = New Windows.Forms.Timer
AddHandler BlinkTimer.Tick, AddressOf Blinker_Tick
With BlinkTimer
.Enabled = True
.Interval = 250
End With
StartBlinker()
End Sub
Public Sub StartBlinker()
SomeTabPage.ImageKey = "light_off.png"
BlinkToggler = False
BlinkTimer.Start()
End Sub
Public Sub StopBlinker()
SomeTabPage.ImageKey = "light_off.png"
BlinkToggler = False
BlinkTimer.Stop()
End Sub
Private Sub Blinker_Tick()
If BlinkToggler Then
SomeTabPage.ImageKey = "light_on.png"
Else
SomeTabPage.ImageKey = "light_off.png"
End If
BlinkToggler = Not BlinkToggler
End Sub
End Class
這是一個快速入侵(有幾件事需要調整,但這是一個開始)手工繪制圖像。
Imports System.Threading
Public Class MyTabControl
Inherits TabControl
Private tabsImages As New Concurrent.ConcurrentDictionary(Of TabPage, List(Of String))
Private tabsImagesKeys As New Concurrent.ConcurrentDictionary(Of TabPage, String)
Private cycleImagesThread As Thread
Private mInterval As Integer = 500
Public Sub New()
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.DrawMode = TabDrawMode.OwnerDrawFixed
cycleImagesThread = New Thread(AddressOf CycleImagesLoop)
cycleImagesThread.Start()
End Sub
Protected Overrides Sub OnHandleCreated(e As EventArgs)
If Me.FindForm IsNot Nothing Then AddHandler CType(Me.FindForm, Form).FormClosing, Sub() cycleImagesThread.Abort()
MyBase.OnHandleCreated(e)
End Sub
Private Sub CycleImagesLoop()
Do
Thread.Sleep(mInterval)
If tabsImagesKeys.Count > 0 Then
For Each tabImageKey In tabsImagesKeys
Dim index = tabsImages(tabImageKey.Key).IndexOf(tabImageKey.Value)
index += 1
index = index Mod tabsImages(tabImageKey.Key).Count
tabsImagesKeys(tabImageKey.Key) = tabsImages(tabImageKey.Key)(index)
Next
Me.Invalidate()
End If
Loop
End Sub
Public Property Interval As Integer
Get
Return mInterval
End Get
Set(value As Integer)
mInterval = value
End Set
End Property
Public Sub SetImages(tabPage As TabPage, images As List(Of String))
If tabsImages.ContainsKey(tabPage) Then
tabsImages(tabPage) = images
Else
tabsImages.TryAdd(tabPage, images)
End If
tabsImagesKeys(tabPage) = images.First()
End Sub
Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs)
Dim g As Graphics = e.Graphics
Dim r As Rectangle = e.Bounds
Dim tab As TabPage = Me.TabPages(e.Index)
Dim tabImage As Image
Using b = New SolidBrush(IIf(e.State = DrawItemState.Selected, Color.White, Color.FromKnownColor(KnownColor.Control)))
g.FillRectangle(b, r)
End Using
If tabsImagesKeys.Count > 0 OrElse Me.ImageList IsNot Nothing Then
If tabsImagesKeys.ContainsKey(tab) Then
tabImage = Me.ImageList.Images(tabsImagesKeys(tab))
g.DrawImageUnscaled(tabImage, r.X + 4, r.Y + (r.Height - tabImage.Height) / 2)
End If
r.X += Me.ImageList.ImageSize.Width + 4
End If
Using b = New SolidBrush(tab.ForeColor)
Dim textSize = g.MeasureString(tab.Text, tab.Font)
g.DrawString(tab.Text, tab.Font, b, r.X, r.Y + (r.Height - textSize.Height) / 2)
End Using
MyBase.OnDrawItem(e)
End Sub
End Class
請按照以下步驟設置控件:
ImageList
控件分配給MyTabControl
並用圖像填充它。 接下來,調用SetImages
方法來定義應在每個選項卡上顯示的圖像。
MyTabControl1.SetImages(TabPage1,New List(Of String)From {“icon.gif”,“icon2.gif”})MyTabControl1.SetImages(TabPage2,New List(Of String)From {“myImage1.gif”,“myImage2。 GIF“})
請注意, SetImages
方法的第二個參數是應該存在於ImageList
上的鍵列表。 控制將完成剩下的工作......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.