Results 1 to 3 of 3

Thread: [RESOLVED] Example diffrent color for a specific value in a datagridviewcombobox column

  1. #1

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Resolved [RESOLVED] Example diffrent color for a specific value in a datagridviewcombobox column

    Hi All,

    I was trying to show items in a datagridview and couldn't find a complete solution to this problem.
    Why? I wanted to visualize to the user the diffrence if they opted for certain values. In mycase certain choises would show phonenumbers on intranet.

    To show how I wil leave the control names default. To recreate the the project. Start a windows form application, place a datagridview, and 2 bindingsources on the form

    To start we need some data to show and a list to choose from.
    To make a simple example I chosen to make a person class containing an Id, Name and PositionId
    If the Position is a staff position it should be blue others should remain the default style
    But lets start with the colorScheme Interface so we can store the colorscheme we want to show for a certain positionitem in the datagrdview
    It wil need back and forecolors but also colors for teh item whilst selected. To show the Displaymember we want to see I've also added the toString property that should shadow the toString of the object.

    Code:
    Public Interface IDatagridViewColorScheme
    
        Property ForeColor() As Color
        Property BackColor() As Color
        Property SelectionForeColor() As Color
        Property SelectionBackColor() As Color
        ReadOnly Property ToString() As String
    End Interface
    and a person Interface
    Code:
    Public Interface IPerson
    
        Property Id() As Integer
        Property Name() As String
        Property PositionId() As Integer
    
    End Interface
    We need a interface for the postions as well
    I know we can do without interfaces but I won't, and the IDatagridViewColorScheme
    will help making this code reusable.
    Code:
    Public Interface IPosition
    
        Inherits IDatagridViewColorScheme
    
        Property Id() As Integer
        Property PositionDesription() As String
        Property IsManaging() As Boolean
    
    End Interface
    Next step make the objects we need:
    Code:
    Public Class Person
        Implements IPerson
    
        Private _Id As Integer
        Private _Name As String
        Private _PositionId As Integer
    
    
        Public Property Id() As Integer Implements IPerson.Id
            Get
                Return _Id
            End Get
            Set(ByVal value As Integer)
                _Id = value
            End Set
        End Property
    
        Public Property Name() As String Implements IPerson.Name
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
    
        Public Property PositionId() As Integer Implements IPerson.PositionId
            Get
                Return _PositionId
            End Get
            Set(ByVal value As Integer)
                _PositionId = value
            End Set
        End Property
    End Class
    
    Public Class Position
    
        Implements IPosition
    
        Private _Id As Integer
        Private _PositionDesription As String
        Private _IsManaging As Boolean
        Private _ForeColor As Color
        Private _BackColor As Color
        Private _SelectionForeColor As Color
        Private _SelectionBackColor As Color
    
        Public Property BackColor() As System.Drawing.Color Implements IDatagridViewColorScheme.BackColor
            Get
                Return _BackColor
            End Get
            Set(ByVal value As System.Drawing.Color)
                _BackColor = value
            End Set
        End Property
    
        Public Property ForeColor() As System.Drawing.Color Implements IDatagridViewColorScheme.ForeColor
            Get
                Return _ForeColor
            End Get
            Set(ByVal value As System.Drawing.Color)
                _ForeColor = value
            End Set
        End Property
    
        Public Property SelectionBackColor() As System.Drawing.Color Implements IDatagridViewColorScheme.SelectionBackColor
            Get
                Return _SelectionBackColor
            End Get
            Set(ByVal value As System.Drawing.Color)
                _SelectionBackColor = value
            End Set
        End Property
    
        Public Property SelectionForeColor() As System.Drawing.Color Implements IDatagridViewColorScheme.SelectionForeColor
            Get
                Return _SelectionForeColor
            End Get
            Set(ByVal value As System.Drawing.Color)
                _SelectionForeColor = value
            End Set
        End Property
    
        Public Property Id() As Integer Implements IPosition.Id
            Get
                Return _Id
            End Get
            Set(ByVal value As Integer)
                _Id = value
            End Set
        End Property
    
        Public Property IsManaging() As Boolean Implements IPosition.IsManaging
            Get
                Return _IsManaging
            End Get
            Set(ByVal value As Boolean)
                _IsManaging = value
            End Set
        End Property
    
        Public Property PositionDesription() As String Implements IPosition.PositionDesription
            Get
                Return _PositionDesription
            End Get
            Set(ByVal value As String)
                _PositionDesription = value
            End Set
        End Property
    
        Public Shadows ReadOnly Property ToString() As String Implements IDatagridViewColorScheme.ToString
            Get
                Return _PositionDesription
            End Get
            
        End Property
    End Class
    Continue at my next post....
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  2. #2

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: Example diffrent color for a specific value in a datagridviewcombobox column

    Now we need to build the project and do some stuff in the designer.
    - Set the datasource property of bindingsource1 to the person class
    - Set BindingSource2 to the positionclass.
    - Set the datasource for the datagridview to bindingsource1
    - choose to edit the datagridview and select the PositionIdColumn.
    - Set the Columntype to datagridviewComboboxColumn
    - Set the datasource for the column on bindingsource2 and select the Id for the value and the positionDescription for the displaymember of the positionIdColumn and close the columneditor
    - Do some other stuff to meke the datagridview look nice (optional)

    Now we need to create the data to play with
    and set the bindingsources
    Code:
    Public Class Form1
    
    
        Private _DefaultCellstyle As DataGridViewCellStyle
        Private _PositionList As New List(Of Position)
        Private _PersonList As New List(Of Person)
    
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    
            Dim PositionNames() As String = {"General employee", "Helpdesk employee", "Helpdesk manager", "Financial manager", "finance employee"}
            Dim PersonNames() As String = {"John", "Alice", "Joe", "Sue", "Jan"}
            Dim Ps As Position
            Dim Pers As Person
    
    
            _DefaultCellStyle = Me.DataGridView1.DefaultCellStyle.Clone
    
    
            For I As Integer = 0 To 4
                Ps = New Position
                Ps.PositionDesription = PositionNames(I)
                Ps.Id = I + 1
                If Ps.PositionDesription.IndexOf("manager") >= 0 Then
                    Ps.IsManaging = True
                    'Create a  special look for these items
                    Ps.SelectionBackColor = Color.DarkBlue
                    Ps.SelectionForeColor = Color.LightSkyBlue
                    Ps.BackColor = Color.BlanchedAlmond
                    Ps.ForeColor = Color.Blue
                Else
                    'This is just to make life easy.
                    Ps.SelectionBackColor = _DefaultCellStyle.SelectionBackColor
                    Ps.SelectionForeColor = _DefaultCellStyle.SelectionForeColor
                    Ps.BackColor = _DefaultCellStyle.BackColor
                    Ps.ForeColor = _DefaultCellStyle.ForeColor
                End If
                _PositionList.Add(Ps)
            Next
    
    
            For I As Integer = 0 To 4
                Pers = New Person
                Pers.Name = PersonNames(I)
                Pers.Id = I + 1
                Pers.PositionId = I + 1
                _PersonList.Add(Pers)
            Next
    
            Me.BindingSource1.DataSource = _PersonList
            Me.BindingSource2.DataSource = _PositionList
    
        End Sub
    
    End Class
    Now we need to override the DataGridViewComboBoxColumn with something we make our selves.
    Code:
    Imports System
    Imports System.Windows.Forms
    Imports System.ComponentModel
    
    Public Class DropDownListColumn
        Inherits DataGridViewComboBoxColumn
    
        Public Sub New()
            'Set the type used in the DataGridView
            Me.CellTemplate = New DropDownListCell
        End Sub
    End Class
    
    Public Class DropDownListCell
        Inherits DataGridViewComboBoxCell
    
        Public Overrides ReadOnly Property EditType() As Type
            Get
                ' Return the type of the editing contol that 
                ' the DropDownListCell uses.
                Return GetType(DropDownListEditingControl)
            End Get
        End Property
    
        Protected Overrides Function GetFormattedValue( _
            ByVal value As Object, ByVal rowIndex As Integer, _
            ByRef cellStyle As System.Windows.Forms.DataGridViewCellStyle, _
            ByVal valueTypeConverter As System.ComponentModel.TypeConverter, _
            ByVal formattedValueTypeConverter As System.ComponentModel.TypeConverter, _
            ByVal context As System.Windows.Forms.DataGridViewDataErrorContexts) As Object
    
    
            Dim ColorDefinition As IDatagridViewColorScheme
            'Get object that is diplayed in the DataGridView cells with default formatting
            Dim obj As Object = MyBase.GetFormattedValue( _
                    value, rowIndex, cellStyle, _
                    valueTypeConverter, formattedValueTypeConverter, _
                    context)
            'ken de kleuren toe die voor dit item zijn gedefinieerd indien het interface IDatagridviewColumnItemColors wordt ondersteunt
            If Not IsNothing(obj) Then
                If TypeOf obj Is IDatagridViewColorScheme Then
                    ColorDefinition = CType(obj, IDatagridViewColorScheme)
                    cellStyle.ForeColor = ColorDefinition.ForeColor
                    cellStyle.BackColor = ColorDefinition.BackColor
                    cellStyle.SelectionBackColor = ColorDefinition.SelectionBackColor
                    cellStyle.SelectionForeColor = ColorDefinition.SelectionForeColor
                ElseIf TypeOf obj Is ICustomTypeDescriptor Then
                    ColorDefinition = CType(obj.object, IDatagridViewColorScheme)
                    cellStyle.ForeColor = ColorDefinition.ForeColor
                    cellStyle.BackColor = ColorDefinition.BackColor
                    cellStyle.SelectionBackColor = ColorDefinition.SelectionBackColor
                    cellStyle.SelectionForeColor = ColorDefinition.SelectionForeColor
                End If
            End If
    
            Return obj
        End Function
    End Class
    
    Public Class DropDownListEditingControl
        Inherits DataGridViewComboBoxEditingControl
    
        Public Sub New()
            MyBase.New()
            'Set some default properties
    
            'This will cause the DrawItem event to raise,
            'allowing changes to be made to the appearance
            'at run time
            Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
    
            'Make this a DropDownList 
            Me.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        Protected Overrides Sub OnDrawItem( _
            ByVal e As System.Windows.Forms.DrawItemEventArgs)
    
            ' Create a rectagle the size of the item container
            Dim rec As New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)
            Dim ColorDefinition As IDatagridViewColorScheme
    
            If Me.Enabled Then
                'If the item is being pointed to Selection it
    
                If e.Index > -1 Then
                    Dim obj As Object = Me.Items(e.Index)
                    If TypeOf obj Is IDatagridViewColorScheme Then
                        ColorDefinition = CType(obj, IDatagridViewColorScheme)
                        If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                            e.Graphics.FillRectangle(New SolidBrush(ColorDefinition.SelectionBackColor), rec)
                        Else
                            e.Graphics.FillRectangle(New SolidBrush(ColorDefinition.BackColor), rec)
                        End If
                    Else
                        If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                            e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.Highlight), rec)
                        Else
                            e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.ControlLightLight), rec)
                        End If
                    End If
                Else
                    If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                        e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.Highlight), rec)
                    Else
                        e.Graphics.FillRectangle(New SolidBrush(System.Drawing.SystemColors.ControlLight), rec)
                    End If
                End If
            Else
                'Grey out the box it is disablbed
                e.Graphics.FillRectangle( _
                New SolidBrush(System.Drawing.SystemColors.Control), rec)
            End If
    
            'If there is an item
            If e.Index > -1 Then
                Dim obj As Object = Me.Items(e.Index)
                If TypeOf obj Is IDatagridViewColorScheme Then
                    ColorDefinition = CType(obj, IDatagridViewColorScheme)
                    'If the item is selected Selection it            
                    If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                        Dim SelectionedText As New SolidBrush(ColorDefinition.SelectionForeColor)
                        e.Graphics.DrawString(ColorDefinition.ToString, e.Font, SelectionedText, rec)
                    Else
                        Dim NormalText As New SolidBrush(ColorDefinition.ForeColor)
                        e.Graphics.DrawString(ColorDefinition.ToString, e.Font, NormalText, rec)
                    End If
                Else
                    If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                        Dim SelectionedText As New SolidBrush(System.Drawing.SystemColors.HighlightText)
                        e.Graphics.DrawString(obj.ToString, e.Font, SelectionedText, rec)
                    Else
                        Dim NormalText As New SolidBrush(System.Drawing.SystemColors.ControlText)
                        e.Graphics.DrawString(obj.ToString, e.Font, NormalText, rec)
                    End If
                End If
            Else
                Dim NormalText As New SolidBrush(System.Drawing.SystemColors.ControlText)
                e.Graphics.DrawString("", e.Font, NormalText, rec)
            End If
    
        End Sub
    End Class
    To implement this we need to build project first so intelisense knows out objects.

    After these steps we need to go in the designer of the form and adjust it a bit
    To implement the DataGridViewTextBoxColumn
    We need to alter just 1 line from:
    Me.PositionIdDataGridViewTextBoxColumn = New System.Windows.Forms.DropDownListColumn

    Me.PositionIdDataGridViewTextBoxColumn = New Tutorial.DropDownListColumn
    Where Tutorial should be replaced by the name of your application.
    And Now our overriden DropDownListColumn is used
    If we now run the application the items in the dropdown are colored the way we want
    but we don't see them in the datagridview

    continue in my next post
    Last edited by Dnereb; Dec 23rd, 2010 at 10:22 AM.
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

  3. #3

    Thread Starter
    Fanatic Member Dnereb's Avatar
    Join Date
    Aug 2005
    Location
    Netherlands
    Posts
    863

    Re: Example diffrent color for a specific value in a datagridviewcombobox column

    To make that happen we need to alter the code in the form to this
    Code:
    Public Class Form1
    
    
        Private _DefaultCellstyle As DataGridViewCellStyle
        Private _Initialized As Boolean
        Private _PositionList As New List(Of Position)
        Private _PersonList As New List(Of Person)
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    
            Dim PositionNames() As String = {"General employee", "Helpdesk employee", "Helpdesk manager", "Financial manager", "finance employee"}
            Dim PersonNames() As String = {"John", "Alice", "Joe", "Sue", "Jan"}
            Dim Ps As Position
            Dim Pers As Person
    
    
            _DefaultCellstyle = Me.DataGridView1.DefaultCellStyle.Clone
    
    
            For I As Integer = 0 To 4
                Ps = New Position
                Ps.PositionDesription = PositionNames(I)
                Ps.Id = I + 1
                If Ps.PositionDesription.IndexOf("manager") >= 0 Then
                    Ps.IsManaging = True
                    Ps.SelectionBackColor = Color.DarkBlue
                    Ps.SelectionForeColor = Color.LightSkyBlue
                    Ps.BackColor = Color.BlanchedAlmond
                    Ps.ForeColor = Color.Blue
                Else
                    'This is just to make life easy.
                    Ps.SelectionBackColor = _DefaultCellstyle.SelectionBackColor
                    Ps.SelectionForeColor = _DefaultCellstyle.SelectionForeColor
                    Ps.BackColor = _DefaultCellstyle.BackColor
                    Ps.ForeColor = _DefaultCellstyle.ForeColor
                End If
                _PositionList.Add(Ps)
            Next
    
    
            For I As Integer = 0 To 4
                Pers = New Person
                Pers.Name = PersonNames(I)
                Pers.Id = I + 1
                Pers.PositionId = I + 1
                _PersonList.Add(Pers)
            Next
    
            Me.BindingSource1.DataSource = _PersonList
            Me.BindingSource2.DataSource = _PositionList
    
        End Sub
    'Make sure errors while creating the form aren't shown.
        Private Sub DatagridView1_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
            'To prevent errors 
            If Not _Initialized Or Me.Disposing Then
                e.ThrowException = False
            End If
    
        End Sub
        'We need to do some work when a row is added
        'actually we need to determine what colors the cells need to be.
        Private Sub DataGridView_RowsAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded
    
            Dim RW As DataGridViewRow
            Dim Cl As DataGridViewCell
            Dim Tel As Person
    
            Try
                For I As Integer = e.RowIndex To e.RowIndex + e.RowCount
                    RW = Me.DataGridView1.Rows(I)
                    Cl = RW.Cells(PositionIdDataGridViewTextBoxColumn.Name)
                    Tel = RW.DataBoundItem
                    If Tel IsNot Nothing Then
                        Cl.Style.BackColor = _DefaultCellstyle.BackColor
                        Cl.Style.ForeColor = _DefaultCellstyle.ForeColor
                        Cl.Style.SelectionBackColor = _DefaultCellstyle.SelectionBackColor
                        Cl.Style.SelectionForeColor = _DefaultCellstyle.SelectionForeColor
    
                        For Each SoortTel As Position In _PositionList
                            'when Found duplicate the cellstyle colors to this Cell, this Is why I also filled in the default colors
                            'it saves some time at a crucial moment.
                            If SoortTel.Id = Tel.PositionId Then
                                Cl.Style.BackColor = SoortTel.BackColor
                                Cl.Style.ForeColor = SoortTel.ForeColor
                                Cl.Style.SelectionBackColor = SoortTel.SelectionBackColor
                                Cl.Style.SelectionForeColor = SoortTel.SelectionForeColor
                                Exit For
                            End If
    
                        Next
                    End If
                Next
            Catch ex As Exception
                'Do whatever you want here, this is just a simple example
            End Try
    
        End Sub
    
        'To minimize the amount of statments the validated event will only be used to set the colors
        'if a cell is edited in this column, we can not set the cellstyle here as it is going to be edited.
        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            Dim EditCtrl As DataGridViewComboBoxEditingControl
    
            If TypeOf (e.Control) Is DataGridViewComboBoxEditingControl Then
                'Er word een textbox in het grid geedit.
                EditCtrl = e.Control
                If EditCtrl.EditingControlDataGridView.CurrentCell.OwningColumn Is PositionIdDataGridViewTextBoxColumn Then
                    'We are in the right column
                    'Add a handler to the CellValidated so the cellstyle can be adjust to the value after editting.
                    AddHandler Me.DataGridView1.CellValidated, AddressOf DataGridView1_CellValidated
                End If
    
            End If
        End Sub
        'And now we set the colors for the cell
        'As only the cells in the dropdownboxcolumn will 
        Private Sub DataGridView1_CellValidated(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs)
    
            Dim Cl As DataGridViewCell
            Dim RW As DataGridViewRow
            Dim Tel As Person
    
            If e.RowIndex >= 0 Then
                RW = DataGridView1.Rows(e.RowIndex)
                Cl = RW.Cells(e.ColumnIndex)
                Tel = RW.DataBoundItem
    
                If Tel IsNot Nothing Then
                    Cl.Style.ForeColor = _DefaultCellstyle.ForeColor
                    Cl.Style.BackColor = _DefaultCellstyle.BackColor
                    Cl.Style.SelectionForeColor = _DefaultCellstyle.SelectionForeColor
                    Cl.Style.SelectionBackColor = _DefaultCellstyle.SelectionBackColor
                    For Each SoortTel As Position In _PositionList
                        If SoortTel.Id = Tel.PositionId Then
                            Cl.Style.ForeColor = SoortTel.ForeColor
                            Cl.Style.BackColor = SoortTel.BackColor
                            Cl.Style.SelectionForeColor = SoortTel.SelectionForeColor
                            Cl.Style.SelectionBackColor = SoortTel.SelectionBackColor
                            Exit For
                        End If
    
                    Next
                End If
            End If
    
            RemoveHandler DataGridView1.CellValidated, AddressOf DataGridView1_CellValidated
        End Sub
    End Class
    Have Fun!
    why can't programmers keep and 31 Oct and 25 dec apart. Why Rating is Useful
    for every question you ask provide an answer on another thread.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width