views:

97

answers:

4

For a Winforms application, I'm looking for a control which is able to show text and supports individual line colors (fore and background colors per line).

For instance, I'd like to have line 1 with a green background color and line 4 with red.

+1  A: 

If you don't need editing facilities you can use either a ListView control (in Details mode) or a TreeControl for this. Editing with these controls would be limited to one line at a time (like a rename facility in Windows Explorer).

If you do need editing facilities then you'll need a RichTextBox based control as ChrisF suggests.

Matt Breckon
+1  A: 

It sounds like you might need a Rich Text Editor control.

There are plenty of 3rd party controls about - including one on CodeProject

ChrisF
+4  A: 

A ListView control is probably the easiest thing for what you need (as long as it is just for display). Set its View property to List. Each item is a ListViewItem, on which you can set the foreground and background colours.

adrianbanks
+1  A: 

In the past, I've used a customized combobox for this type of control.  I set the DrawMode to OwnerDrawVariable in the constructor, and Override the OnDrawItem method.  That way you can draw the background for each item in the combobox with whatever color or style that you want.

The code below draws every other item with a gray background, like the images shown in this post, but you can customize it however you want in the OnDrawItem method. this example also supports multiple columns and text-wrapping in the combobox, but that just complicates things needlessly.

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

        //Don't draw the custom area if in DesignMode.
        If Me.DesignMode Then Return

        //Don't draw the custom area if the index is -1.
        If e.Index = -1 Then Return

        e.DrawBackground()

        Dim boundsRect As Rectangle = e.Bounds
        //Shift everything just a bit to the right.
        Dim lastRight As Integer = 2

        Dim brushForeColor As Color
        Dim bckColor As Color
        Dim lineColor As Color

        If Not (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
           //Item is not selected, use _BackColorOdd and _BackColorEven.
           If e.Index Mod 2 = 0 Then
              bckColor = _BackColorEven
           Else
              bckColor = _BackColorOdd
           End If
           //Use black text color.
           brushForeColor = Color.Black
           //Use dark line color.
           lineColor = _BackColorSelected
        Else
           //Item is selected, use the 'Selected' background color.
           bckColor = _BackColorSelected
           //Item is selected, use white font color.
           brushForeColor = Color.White
           //Use white line color.
           lineColor = Color.White
        End If

        //Draw the background rectangle with the appropriate color.
        Using brushBackColor As New SolidBrush(bckColor)
           e.Graphics.FillRectangle(brushBackColor, e.Bounds)
        End Using

        Using linePen As New Pen(lineColor)
           Using brsh As New SolidBrush(brushForeColor)

              //This is the multi-column stuff.
              For colIndex As Integer = 0 To _ColumnNames.Count - 1
                 //Variant(Object) type used to support different data types in each column.
                 Dim itm As Object
                 itm = FilterItemOnProperty(Items(e.Index), _ColumnNames(colIndex))

                 boundsRect.X = lastRight
                 boundsRect.Width = _ColumnWidths(colIndex)
                 lastRight = boundsRect.Right


                    e.Graphics.DrawString(itm, Me.Font, brsh, boundsRect)

                 //Draw a divider line.
                 If colIndex < _ColumnNames.Count - 1 Then
                    e.Graphics.DrawLine(linePen, boundsRect.Right, boundsRect.Top, _
                                        boundsRect.Right, boundsRect.Bottom)
                 End If
              Next
           End Using
        End Using

     End Sub

This might be a little bit overkill for what you are wanting, but it will do the trick.

Stewbob