2013-01-11 19 views
6

यहां मेरा दिमाग खोने के बारे में। मैं इस नाबालिग को हल करने की कोशिश कर रहे एक घंटे के लिए गुगल रहा हूं, लेकिन अविश्वसनीय रूप से बढ़ती समस्या।टैब के आइकन को बदलते समय टैबकंट्रोल झिलमिलाहट

मेरे पास दो टैब के साथ मेरे फॉर्म पर TabControl है। उनमें से प्रत्येक टैब में 16x16 आइकन और कुछ टेक्स्ट है। यहां कुछ भी पागल नहीं चल रहा है।

मुझे कुछ परिस्थितियों में एक टैब आइकन झपकी बनाने की आवश्यकता है। इसलिए मैंने दो छवियां, light_on.png और light_off.png बनाई और द्वारा उपयोग किए गए में उन्हें जोड़ा। मैंने एक पृष्ठभूमि टाइमर स्थापित किया जो दो छवियों के बीच एक झपकी आइकन अनुकरण करने के लिए टॉगल करता है। ठीक काम करता है।

हालांकि, यह सभी टैब हेडर को फिर से निकालने का कारण बन रहा है, जो उन्हें झिलमिलाहट कर रहा है।

TabControl डबल-बफरिंग का समर्थन नहीं करता है, इससे कोई फर्क नहीं पड़ता कि आप क्या करने का प्रयास करते हैं।

मैंने पाया लोगों को कुछ इस कोड का उपयोग झिलमिलाते taming सफलता:

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 
+0

... मैं यहां से बाहर हो सकता हूं, लेकिन एनिमेटेड gif के बारे में क्या है और फिर आपको इसके बारे में चिंता करने की ज़रूरत नहीं है? –

+0

टैबकंट्रोल को डबल-बफर नहीं किया जा सकता है, इसलिए आपको शायद इस सीमा के साथ रहना होगा या स्क्रीन पर कहीं और फ्लैश करने के लिए अपने चमकती रोशनी बल्बों को डिजाइन करना होगा। – LarsTech

+0

@ जॉन बुस्टोस मैंने एनिमेटेड gif की कोशिश की, काम नहीं करता (एनिमेट नहीं करता)। यही वह सुझाव है जिसे मैं ढूंढ रहा था, धन्यवाद। – user1003916

उत्तर

3

यह एक त्वरित हैक है (वहाँ कई चीजें फेरबदल की आवश्यकता है, लेकिन यह एक शुरुआत है) हाथ से छवियों के ड्राइंग करना है।

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 

नियंत्रण सेटअप करने के लिए निम्न चरणों का पालन करें:

सभी की
  1. पहले, MyTabControl के लिए एक ImageList नियंत्रण आवंटित और छवियों के साथ भरें।
  2. अगला, प्रत्येक टैब पर कौन सी छवियां प्रदर्शित की जानी चाहिए, यह निर्धारित करने के लिए SetImages विधि पर कॉल करें।

    MyTabControl1.SetImages (TabPage1, न्यू सूची (स्ट्रिंग के) { "icon.gif", "icon2.gif"} से) MyTabControl1.SetImages (TabPage2, न्यू (स्ट्रिंग की) सूची { "myImage1.gif से "" myImage2.gif "})

ध्यान दें कि SetImages विधि के दूसरे पैरामीटर कुंजियां जो करना होता है की एक सूची है ImageList पर मौजूद है। नियंत्रण बाकी करेगा ...

+0

ग्रेट पोस्ट, धन्यवाद। – user1003916