Appointment Calendar for a month on one form

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
Thats OK, It seems to do it and then quickly overwrites it without doing CellPainting.

So somewhere in the assigning data to the datagridivew cells it stop doing cellpainting and load the data directly on assignment! Weird!

I'll keep at it, but its not easy, as there are many many questions on the internet with very few answers, which is a shame as its a fabulous feature!
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,412
Location
Norway
Programming Experience
10+
You start out using e.CellBounds and also use this to draw a rectangle in each cell, then you change to some other coordinates for text. What if you continue to use e.CellBounds also when drawing text?
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
You start out using e.CellBounds and also use this to draw a rectangle in each cell, then you change to some other coordinates for text. What if you continue to use e.CellBounds also when drawing text?
I'll try it tomorrow...
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
Here's some test code I tried:
VB.NET:
Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim fieldText = "Red
Green
Blue"
        Dim table As New DataTable

        table.Columns.Add("First", GetType(String))
        table.Columns.Add("Second", GetType(String))

        For i = 1 To 3
            table.Rows.Add(fieldText, fieldText)
        Next

        DataGridView1.DataSource = table
    End Sub

    Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
        If e.ColumnIndex >= 0 AndAlso e.RowIndex >= 0 AndAlso e.Value IsNot Nothing Then
            e.PaintBackground(e.ClipBounds, True)

            Dim prefix = String.Empty

            For Each line In CStr(e.Value).Split({Environment.NewLine}, StringSplitOptions.None)
                Dim lineText = prefix & line
                Dim colour = Color.FromName(line)

                Using brush As New SolidBrush(colour)
                    e.Graphics.DrawString(lineText, e.CellStyle.Font, brush, e.CellBounds)
                End Using

                prefix &= Environment.NewLine
            Next

            e.Handled = True
        End If
    End Sub

End Class
Here's the result:
CellPainting Demo.png


Note that I drew a multiline string one line at a time to draw each line in a different colour. I prefixed the text for each line with the required number of line breaks to push it down the appropriate distance.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
Ohh, I'm reading too fast again 🤨
So im thinking about other options....
How about creating a list object assign text values colour in and then assign list object to a cell in datagridview.

No need for cellpainting event!
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
So im thinking about other options....
How about creating a list object assign text values colour in and then assign list object to a cell in datagridview.

No need for cellpainting event!
I don't know exactly what you mean by that but it certainly doesn't sound like something useful; at least, not on its own. If you don't handle that event or use a custom cell type that does its own custom painting, you're just going to end up with a single line of text in a single colour. Whatever data you store in the cell, you still need to interpret it somewhere to display it in the way you want, which is what the event handler is for.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
Here's some test code I tried:
VB.NET:
Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim fieldText = "Red
Green
Blue"
        Dim table As New DataTable

        table.Columns.Add("First", GetType(String))
        table.Columns.Add("Second", GetType(String))

        For i = 1 To 3
            table.Rows.Add(fieldText, fieldText)
        Next

        DataGridView1.DataSource = table
    End Sub

    Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
        If e.ColumnIndex >= 0 AndAlso e.RowIndex >= 0 AndAlso e.Value IsNot Nothing Then
            e.PaintBackground(e.ClipBounds, True)

            Dim prefix = String.Empty

            For Each line In CStr(e.Value).Split({Environment.NewLine}, StringSplitOptions.None)
                Dim lineText = prefix & line
                Dim colour = Color.FromName(line)

                Using brush As New SolidBrush(colour)
                    e.Graphics.DrawString(lineText, e.CellStyle.Font, brush, e.CellBounds)
                End Using

                prefix &= Environment.NewLine
            Next

            e.Handled = True
        End If
    End Sub

End Class
Here's the result:
View attachment 4497

Note that I drew a multiline string one line at a time to draw each line in a different colour. I prefixed the text for each line with the required number of line breaks to push it down the appropriate distance.
Looks great I will copy your code and test. Can you change the background color and not wrap the text.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
Can you [...] not wrap the text.
Given that the Graphics.DrawString method is what is being used to draw the text, maybe you should research that to see what it can and can't do. Look first, ask questions later.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
Also can you center the top text line and left align lines below?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
Also can you center the top text line and left align lines below?
You probably hadn't read my previous post when you wrote this but I will repeat anyway: look first, ask questions later. DrawString is what draws the string so that is where you will control how the string is drawn. READ THE DOCUMENTATION.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
You probably hadn't read my previous post when you wrote this but I will repeat anyway: look first, ask questions later. DrawString is what draws the string so that is where you will control how the string is drawn. READ THE DOCUMENTATION.
No I read that.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,412
Location
Norway
Programming Experience
10+

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
So I've been working with your code and while I can assign a table with data to the datagridview and change the color of the text, it seems clear that it cant do the things I want it to which is such a shame.

It always wraps the text (which I dont want!) I can't change the background of the text per line of text. I cant add a scroll bar in the cell if if there too many lines either.

See image below of how Id like it too look.. Date right or centered at the top. Each appointment has its own line with a diff back color and if ther more than 4 lines a scroll bar appears.

It doesnt sound a lot but I think CellPainting isnt going to cut it! What alternative do we have?

1585055452494.png


Here my Claendar so far with data loaded from SQL Server, just no formatting being appled!

1585055830552.png
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
It always wraps the text (which I dont want!)
No it doesn't. I told you to read the documentation for the DrawString method and @JohnH specifically told you that it was the StringFormat parameter that controlled wrapping. Did you look into that at all? It's hard to see that you could have. All you had to do was change this:
VB.NET:
e.Graphics.DrawString(lineText, e.CellStyle.Font, brush, e.CellBounds)
to this:
VB.NET:
e.Graphics.DrawString(lineText, e.CellStyle.Font, brush, e.CellBounds, New StringFormat(StringFormatFlags.NoWrap))
Not hard to work out if you had taken the advice provided. I'm not providing this specifically to help you, but rather to show how easy it was to help yourself. If you're not prepared to do that, I'm not prepared to do any more either.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,295
Location
Sydney, Australia
Programming Experience
10+
I can't change the background of the text per line of text.
Of course you can. You can draw whatever you want using GDI+. The "background" is just the first layer that you draw. If you want multiple different-coloured backgrounds then you call FillRectangle multiple times, then call DrawString to draw text on top of that.
I cant add a scroll bar in the cell if if there too many lines either.
Of course you can't. There's no control in the cell so how could there be a scrollbar? If you had researched how the DataGridView control worked then you'd know that cells don't contain controls by default and are simply a drawn representation of data, which is why that CellPainting event exists in the first place. The only time a control exists in a cell is when you are editing it. If, as I suggested earlier in this thread, you created a custom column, cell and editing control then you could embed an editing control with a scrollbar when a cell gets clicked. That's what happens with all cells, for instance, a combo box cell doesn't contain a ComboBox control by default. It only contains a drawing of a ComboBox, depending on the configuration. When you start editing a cell, which may happen when you enter the cell or may take further action, a ComboBox control is created and embedded in the cell, then removed when the editing finishes.
What alternative do we have?
If only I'd answered that question in the very first reply to this thread.
 

divjoy

Well-known member
Joined
Aug 25, 2013
Messages
129
Programming Experience
1-3
Well that me told ! 😞😞😞. But thank for your help anyways. Clearly it can be done but with a lot of work and at the moment I don't have the time to reseach all the different Drawstring methods of which there are many!. Not to mention cell boundary and rectangles together with points. It will have to be a project whenever I get more time to spend on it.
 
Top Bottom