Visualizza il feed RSS

MarcoGG : Articoli Blog

[VB.NET] Un Color Picker per Known Colors

Valuta questo inserimento
di pubblicato il 16-04-2011 alle 09:43 (4859 Visite)
Descrizione :
Un mio controllo Color Picker tipo ComboBox per la scelta veloce di colori dalla palette dei Known Colors di Visual Studio.

Tratto da :
http://forum.masterdrive.it/visual-b...-vb-net-52885/

Mi sono divertito a creare questo controllo, ispirato anche dalla discussione da cui è tratto.
Si tratta di una Classe che eredita da ComboBox, e che permette la selezione di un Colore tra i Known Colors di VS, ma escludendo i colori di sistema e il Transparent.
Tra le varie caratteristiche, la Proprietà PickedColor e l'Evento OnPickedColorChanged(), per rendere ancora più semplice l'uso dal codice esterno.

Inoltre ci sono due modalità di visualizzazione dei colori alternative :

1. Standard alfabetica : l'insieme dei colori disponibili viene ordinato alfabeticamente A-Z.

2. HSB : l'insieme dei colori disponibili viene ordinato in base allo schema H-S-B, ossia Hue --> Saturation --> Brightness.
Faccio notare che questo tipo di ordinamento è lo stesso identico della palette dei Colors sulla scheda Web in qualsiasi selezione di colori del designer di Visual Studio :



E' possibile passare dall'una all'altra semplicemente con la Proprietà OrderByHSB : se False imposta l'ordinamento alfabetico, se True, tramite istanza della Inner Class ColorComparer, imposta l'ordinamento HSB.

--> Classe ColorPickerCombo :

codice:
Imports System.ComponentModel

Public Class ColorPickerCombo
    Inherits ComboBox

    Private Class ColorComparer
        Implements IComparer(Of String)

        Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements IComparer(Of String).Compare

            Dim cx As Color = Color.FromName(x)
            Dim cy As Color = Color.FromName(y)

            If cx.GetHue = cy.GetHue Then
                If cx.GetSaturation = cy.GetSaturation Then
                    Return cx.GetBrightness.CompareTo(cy.GetBrightness)
                Else
                    Return cx.GetSaturation.CompareTo(cy.GetSaturation)
                End If
            Else
                Return cx.GetHue.CompareTo(cy.GetHue)
            End If

        End Function

    End Class

    Private m_colornames As New List(Of String)
    Private m_orderbyhsb As Boolean
    Private m_pickedcolor As Color

    Public Property OrderByHSB As Boolean
        Get
            Return m_orderbyhsb
        End Get
        Set(ByVal value As Boolean)
            m_orderbyhsb = value
            Me.Items.Clear()
            If m_orderbyhsb = True Then
                m_colornames.Sort(New ColorComparer)
            Else
                m_colornames.Sort()
            End If
            Me.Items.AddRange(m_colornames.ToArray)
            If Me.Items.Count > 0 Then Me.SelectedIndex = 0
        End Set
    End Property

    Public Property PickedColor As Color
        Get
            Return m_pickedcolor
        End Get
        Set(ByVal value As Color)
            Try
                If Not m_colornames.Contains(value.ToKnownColor.ToString) Then Exit Property
            Catch ex As Exception
                Exit Property
            End Try
            m_pickedcolor = value
            Me.SelectedItem = m_pickedcolor.ToKnownColor.ToString
            RaiseEvent OnPickedColorChanged()
        End Set
    End Property

    Public Event OnPickedColorChanged()

    Public Sub New()

        If LicenseManager.UsageMode = LicenseUsageMode.Runtime Then

            Me.DrawMode = DrawMode.OwnerDrawFixed
            Me.DropDownStyle = ComboBoxStyle.DropDownList

            Dim KC As Color
            For Each knclr As KnownColor In [Enum].GetValues(GetType(KnownColor))

                KC = Color.FromKnownColor(knclr)

                If Not KC.IsSystemColor And Not KC = Color.Transparent Then

                    m_colornames.Add(KC.ToKnownColor.ToString)

                End If

            Next

            Me.Items.AddRange(m_colornames.ToArray)
            Me.SelectedIndex = 0

        End If

    End Sub

    Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)

        If e.Index < 0 Then Exit Sub

        Dim h As Integer
        Dim BR As New SolidBrush(Color.FromName(Me.Items(e.Index)))

        e.DrawBackground()

        With e.Graphics
            h = .MeasureString(Me.Items(e.Index), Me.Font).Height
            .FillRectangle(BR, e.Bounds.X, e.Bounds.Y, h * 3, h)
            .DrawString(Me.Items(e.Index).ToString(), Me.Font, Brushes.Black, _
                        New RectangleF(e.Bounds.X + h * 3, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
        End With

        e.DrawFocusRectangle()

    End Sub

    Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs)

        Me.PickedColor = Color.FromName(Me.SelectedItem)

    End Sub

End Class
Su Form ospitante un "CPC", perciò :

codice:
    Private Sub CPC_OnPickedColorChanged() Handles CPC.OnPickedColorChanged

        MioColor = CPC.PickedColor
        '...     

    End Sub

aggiornamento da 26-06-2011 a 17:06 di MarcoGG

Tag: vb.net
Categorie
Programmazione

Commenti

  1. L'avatar di MarcoGG
    Per chiunque abbia giustamente notato qualcosa di "strano" nel Metodo Costruttore della Classe ColorPickerCombo, e mi riferisco all'utilizzo di
    LicenseManager.UsageMode = LicenseUsageMode.Runtime, e voglia approfondire, segnalo anche questa discussione :
    http://forum.masterdrive.it/visual-b...o-items-53846/
    E un Grazie a Fix.