Solved

Custom DataGridView cell definition

Posted on 2006-06-13
11
1,574 Views
Last Modified: 2010-05-18
I have built an extended version of the DataGridView control which is used in an unbound mode and I want to have a custom cell definition for a portion of the matrix. Each custom cell can hold only two characters and each character can have a different backgound color. For example, a cell could have a green space (which would look like a green block, and an "X" with a red background. The colors and characters can change independently. I presume I create a class that inherits "cell" but beyond that it gets a bit fuzzy.
0
Comment
Question by:tmostad
  • 6
  • 5
11 Comments
 
LVL 9

Accepted Solution

by:
lojk earned 500 total points
ID: 16898903
THis was a nightmare in .net1.x but the datgridview makes it sooo easy...
Just handle the paint event for the cell and draw on what you want...

    Private Sub grd_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles grdScheduler.CellPainting, grdModifications.CellPainting
        If e.ColumnIndex = 3 And e.RowIndex >= 0 Then 'Paint The Words on the Status Field
            Dim displayvalue As String = ""
            Select Case UCase(CheckNullString(e.Value)).Substring(0, 1)
                Case "H"
                    displayvalue = "Hold"
                Case "N"
                    displayvalue = "Not Yet Started"
                Case "S"
                    displayvalue = "Succesful"
                Case "Y"
                    displayvalue = "Running"
                Case "F"
                    displayvalue = "Failed"
                Case Else
                    displayvalue = e.Value
            End Select

            DataGridViewDrawCellText(CType(sender, DataGridView), e, displayvalue)
            e.Handled = True
        End If


    End Sub


Public Shared Sub DataGridViewDrawCellText(ByRef objCurrentDataGridView As DataGridView, ByRef objDataGridViewCellPaintingEventArgs As DataGridViewCellPaintingEventArgs, ByVal TextToDraw As String)

        Dim newRect As New Rectangle(objDataGridViewCellPaintingEventArgs.CellBounds.X + 1, objDataGridViewCellPaintingEventArgs.CellBounds.Y + 1, _
                               objDataGridViewCellPaintingEventArgs.CellBounds.Width - 4, objDataGridViewCellPaintingEventArgs.CellBounds.Height - 4)
        Dim backColorBrush As New SolidBrush(objDataGridViewCellPaintingEventArgs.CellStyle.BackColor)
        Dim gridBrush As New SolidBrush(objCurrentDataGridView.GridColor)
        Dim gridLinePen As New Pen(gridBrush)

        Try

            ' Erase the cell.
            objDataGridViewCellPaintingEventArgs.Graphics.FillRectangle(backColorBrush, objDataGridViewCellPaintingEventArgs.CellBounds)

            ' Draw the grid lines (only the right and bottom lines;
            ' DataGridView takes care of the others).
            objDataGridViewCellPaintingEventArgs.Graphics.DrawLine(gridLinePen, objDataGridViewCellPaintingEventArgs.CellBounds.Left, _
                objDataGridViewCellPaintingEventArgs.CellBounds.Bottom - 1, objDataGridViewCellPaintingEventArgs.CellBounds.Right - 1, _
                objDataGridViewCellPaintingEventArgs.CellBounds.Bottom - 1)
            objDataGridViewCellPaintingEventArgs.Graphics.DrawLine(gridLinePen, objDataGridViewCellPaintingEventArgs.CellBounds.Right - 1, _
                objDataGridViewCellPaintingEventArgs.CellBounds.Top, objDataGridViewCellPaintingEventArgs.CellBounds.Right - 1, _
                objDataGridViewCellPaintingEventArgs.CellBounds.Bottom)

            ' Draw the inset highlight box.
            '  objDataGridViewCellPaintingEventArgs.Graphics.DrawRectangle(Pens.Blue, newRect)

            ' Draw the text content of the cell, ignoring alignment.
            If Not (objDataGridViewCellPaintingEventArgs.Value Is Nothing) Then

                objDataGridViewCellPaintingEventArgs.Graphics.DrawString(TextToDraw, objDataGridViewCellPaintingEventArgs.CellStyle.Font, _
                Brushes.Black, objDataGridViewCellPaintingEventArgs.CellBounds.X + 2, objDataGridViewCellPaintingEventArgs.CellBounds.Y + 2, _
                StringFormat.GenericDefault)
            End If
            objDataGridViewCellPaintingEventArgs.Handled = True

        Finally
            gridLinePen.Dispose()
            gridBrush.Dispose()
            backColorBrush.Dispose()
        End Try
    End Sub


In this example i just paint the word 'Hold' where the cell contains 'H' but you could easily change this for your purposes...


hth..
0
 
LVL 9

Expert Comment

by:lojk
ID: 16898909
kudos to the original sample i built that up from, cant remember where it was now...
0
 
LVL 1

Author Comment

by:tmostad
ID: 16900028
I think this example is pretty close but not close enough to answer my main question which is how do I change the background color at the character level. This shows painting the cell background color which I know how to do but cannot find a property to set the background color of a character. Perhaps I don't understand the example well enough and someone needs to simply point out what I am missing. Thanks.
0
 
LVL 1

Author Comment

by:tmostad
ID: 16900033
I reread my original questions and I didn't articulate the the green block and the X with the red background are in the same cell. Maybe this makes the question clearer?
0
 
LVL 9

Expert Comment

by:lojk
ID: 16900692
you just need to paint what you need onto the cell - you have the cell bounds and you need a brush and...

Im not sure what you mean by 'background color at the character level'. To me that is just the layer of pixels drawn before the text is drawn on top- you just need to draw 2 coloured boxes then drawtext the text on top..

If this doesnt solve it you are going to need to implement a new columndisplaytype with  a couple of labels in whose backcolors can be set(although i suspect in that you may end up painting the characters individually), check out your MSDN (DataGridView) for some pretty thorough if not intuitive examples on this...

How to: Host Controls in Windows Forms DataGridView Cells
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclictl/html/e79a9d4e-64ec-41f5-93ec-f5492633cbb2.htm
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 1

Author Comment

by:tmostad
ID: 16903974
I don't know how long you have been at this but I have been around a long time and my early experience dates back to the day when you programmed the CRT controller directly and characters could have background color as well as blink, underline, etc. attributes. This model was nice for doing control console work since it was simple to highlight abnormal status and such although it was not good at all for doing detailed graphics. Of course Windows is raster based and excellent for graphics. I am trying to add in character-based attributes for my app and this is what I am referring to.  I can see how it might be done by creating Font objects and then changing the attributes of the fonts. I was hoping to find some examples to accelerate my learning but the approach you suggest could also work though differently than I had first imagined.
0
 
LVL 9

Expert Comment

by:lojk
ID: 16904925
Im 30 now and learned basic on my Zx Spectrum around '84 and yes i do remember the framebuffer starting at 16384(h4000) for however many (4096 was it?) bytes and then 768 bytes of Color-Code Nybble Pair Bytes for Fore and BackColor. Ah those were the *good* days, when programming assembler was still, well , possible, and computers were still uncool in a superbly retro cool way ;-)

(un)fortunately things have moved on and painting a couple of squares in your desired colours then Drawing the text on will almost certainly be the easiest and quickest way to do this. Like i said you can go down the CustomDataGridViewColumn route if you want but i promise you will regret it if you want this doing quickly (you can always come back later and refactor if you really dont like the paint method).

The only other alternative i can offer you is to

Create A usercontrol to Represent your row, containing labels and textboxes etc
Create a usercontrol to represent a collection of the above row controls
Create all code to make these controls display what you need from a dataset

and manage all of the display and rendering yourself.... *shudders*... I did a very similar thing in VB6 (more than) once, it was (usually) a disaster...

Pre.Net Painting directly to the screen or components was considered fairly hardcore and it is for the reason that it has been made more accessible and thats why we are discussing it as a serious option. Change isnt always bad: Amongst others, GridCell Painting, Object Serialisation (see current Q_21885251), XML (Generally) and in fact the whole .NET concept has changed my coding style in so many good ways (If I squint I can just about see my ZXSpectrum, way, way off in the distance) that im willing to live with a few days of frustation in exchange..
0
 
LVL 1

Author Comment

by:tmostad
ID: 16905571
Thanks for your help. As I think about it more your first answer has begun to make perfect sense. I will include cell attributes which will be characters which will never be confused as cell content. I will strip them off and draw the cell colors based on them then draw the text on top of them.

I am 46 and feeling like an old dog learning a new trick - having fun but synapses don't seem to rewire as quickly they once did. I cut my teeth in the computer biz switching in (via front panel toggle switches) the paper tape bootloader for an Intel 4004 (the 4-bit predecessor to the 8008 which preceeded the 8080). The process sure kept the software light and lean...!
0
 
LVL 9

Expert Comment

by:lojk
ID: 16905674
Its resisting the changes that makes them more difficult to accept.

You are from before *even my time*...

;-)
0
 
LVL 1

Author Comment

by:tmostad
ID: 16914901
BTW - This works beautifully. Thanks for your help.
0
 
LVL 9

Expert Comment

by:lojk
ID: 16915613
Glad to hear it. If you're happy, I'm happy... ;-)

For reference to anybody else trying to achieve the same thing, I'm sure that tmostad will agree with me that it is not as complicated as you think it is, or as it looks and the results can be truly excellent. This is a very basic example but there is almost no limit - Ive seen some great examples for gradient filling cells, painting images and custom progress bars to name but a few.

Another handy tip for this scenario(i.e the next problem on from this) is instead of configuring, for example, drop down controls or checkboxes in columns i  set the columns to readonly and create Context Menu Strips bound to that column. This allows you to present to the user a method of changing the values without affecting the existing painted cell during edit time and these context menu strips can be as complicated as you need (and be setup at load or even popup time)... Catch the Grid_ContextMenuRequested event to make a reference to the current cell about to be edited then on the contextmenu_click set that cell item value to the required value.. Luvvly Jubbly!



0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now