Share via


How to change the Font Size of text in a specified column of DataGridView?

Question

Friday, December 15, 2017 4:55 PM

I want to make the font size of one column of a DataGridView control half the size of the font sizes in the other columns. I can't seem to do this, after trying various combinations of the following

dg.columns(5).defaultcellstyle.font.size = dg.font.size / 2

dg.columns(5).defaultcellstyle.font = new font(dg.font, emsize:= (dg.font.size/2))

etc.

How do you do this? Thanks.

Robert Homes

All replies (13)

Saturday, December 16, 2017 1:45 AM ✅Answered | 1 vote

Hi Robert,

You can do it like this:

dg.Columns(5).DefaultCellStyle.Font _
    = New Font("Times New Roman", dg.DefaultCellStyle.Font.Size / 2, FontStyle.Regular)

# Please change FontName (1st parameter) and FontStyle (3rd parameter) as you like.

Regards,

Ashidacchi


Saturday, December 16, 2017 2:57 AM ✅Answered | 1 vote

Ashidacchi,

Thank you! That's it! Thought I had tried every possible combination of arguments, but not that one. I found that  using your suggestion, I could adjust the size and keep everything else about the font in the specified column the same as the rest of the grid, like this:

   dg.Columns(3).DefaultCellStyle.Font =
         New Font(dg.Font.Name, dg.DefaultCellStyle.Font.Size * 5 / 6, dg.Font.Style)

There were so many combinations of possible arguments in the 13 "overloads" that I must have overlooked this one. I was about to give up!

Robert Homes

 You do realize that by using the DataGridView.Font,  your small font is always going to be the same font used in the Headers,  not the font used for the other Cells which is set using the DataGridView.DefaultCellStyle.Font,  right?   Figured i would ask since you said the user was going to be able to choose different fonts.

If you say it can`t be done then i`ll try it


Friday, December 15, 2017 5:28 PM | 1 vote

Robert,

If you have this kind of questions, than make it yourself easy. 

Create a new project, make a form with a datagridview and edit the columns. 

In the Columnstyle you change the font. You make using solution explorer the designer .vb visible. 

Then you can copy the code.

     'Column1
        '
        DataGridViewCellStyle1.Font = New System.Drawing.Font("Microsoft Sans Serif", 26.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Column1.DefaultCellStyle = DataGridViewCellStyle1
        Me.Column1.HeaderText = "Column1"
        Me.Column1.Name = "Column1"
        '
        'Column2
        '
        DataGridViewCellStyle2.Font = New System.Drawing.Font("Microsoft Sans Serif", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Column2.DefaultCellStyle = DataGridViewCellStyle2
        Me.Column2.HeaderText = "Column2"
        Me.Column2.Name = "Column2"
        '

Of course you can do that also at run time. However, changing a font means always setting a new font, not simply change it. 

Success
Cor


Friday, December 15, 2017 5:33 PM | 1 vote

Robert,

Since you have Dev, have you considered using a DataGrid instead? You can set it in the designer or in code at runtime:

https://www.devexpress.com/Support/Center/Question/Details/Q139793/how-to-set-font-size-of-the-grid

"A problem well stated is a problem half solved.” - Charles F. Kettering


Friday, December 15, 2017 5:57 PM | 1 vote

 I am guessing you must be adding the columns at runtime since you are doing this in code instead of in the Designer window.  In that case,  you can just set a new font using an appropriate size such as Cor has shown.  Unless you are using a rather large font size like 14 or greater for the DataGridView's DefaultCellStyle.Font,  then you will not want to divide it by 2.  That would create a font so small you would not be able to read it.

 You could just subtract 2 or 3 from the DataGridView's DefaultCellStyle.Font.Size when you create the new font for the Column's DefaultCellStyle.Font.  It would still be basically the same thing as Cor has shown but,  you just use the DataGridView's DefaultCellStyle.Font.Size and subtract 2 or three from it.

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.Columns.Add("Column1", "Small Font")
        DataGridView1.Columns.Add("Column2", "Default Font")
        For i As Integer = 0 To 3
            DataGridView1.Rows.Add(New Object() {"Small-" & i.ToString, "Default-" & i.ToString})
        Next

        Dim DefaultFont As Font = DataGridView1.DefaultCellStyle.Font 'get the default cell style font
        DataGridView1.Columns(0).DefaultCellStyle.Font = New Font(DefaultFont.FontFamily, DefaultFont.Size - 2.5F, DefaultFont.Style) 'set the column default cell style to a new font
    End Sub
End Class

 

 

If you say it can`t be done then i`ll try it


Friday, December 15, 2017 7:01 PM

Cor, Thanks for that, but . . .

I already could do that. What I need (want) to do is make the font size in one column 1/2 the size of the rest of the grid font size. I'm finding it hard to get 1/2 of the font size (which is in pixels) and then put the value in the "emsize" argument (which is a "single" type) of the New Font thing.

If I knew what the grid font size was going to be, putting a figure of half that in would be fine. But in my program the user gets to choose the size of the font . . .

Robert Homes


Friday, December 15, 2017 7:04 PM

Frank,

The DevExpress DataGrid (i.e., "Grid Control") is too much for me. It complicates things by adding another layer ("Views") between the Grid control and the rest of its properties, and then uses completely different names and logic for the rest of it. I already know the DataGridView, so I'm sticking with that at least for now, Got so much other stuff to do, I don't have time to learn all the nuances of the Grid Control. That's a good idea, though, and I'm keeping it in mind for later.

Robert Homes


Friday, December 15, 2017 9:26 PM

Frank,

The DevExpress DataGrid (i.e., "Grid Control") is too much for me. It complicates things by adding another layer ("Views") between the Grid control and the rest of its properties, and then uses completely different names and logic for the rest of it. I already know the DataGridView, so I'm sticking with that at least for now, Got so much other stuff to do, I don't have time to learn all the nuances of the Grid Control. That's a good idea, though, and I'm keeping it in mind for later.

Robert Homes

I don't remember a lot about the project that I used in the former example, but I see that I've set up an event handler for it where I'm changing the "look" based on a parameter (GridView.RowCellStyle):

    Private Sub GridView1_RowCellStyle(sender As Object, _
                                       e As DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs) _
                                       Handles GridView1.RowCellStyle

        If GridView1.RowCount > 0 AndAlso _
            calculatedResultsList IsNot Nothing AndAlso _
            calculatedResultsList.Count > 0 Then

            Dim View As GridView = DirectCast(sender, GridView)

            If e.Column.FieldName = "TotalMinutes" Then
                Dim totalMinutes As Double = CDbl(View.GetRowCellValue(e.RowHandle, View.Columns("TotalMinutes")))

                Dim veryGoodThreshold As Double = 0
                Dim cautionThreshold As Double = 0
                Dim warningThreshold As Double = 0

                If calculatedResultsList(0).Group.Contains("47") Then
                    veryGoodThreshold = 45
                    cautionThreshold = 47.5
                    warningThreshold = 48

                ElseIf calculatedResultsList(0).Group.Contains("56") Then
                    veryGoodThreshold = 55
                    cautionThreshold = 56.5
                    warningThreshold = 57
                End If

                e.Appearance.GradientMode = Drawing2D.LinearGradientMode.Vertical

                If totalMinutes <= veryGoodThreshold Then
                    e.Appearance.BackColor = Color.Green
                    e.Appearance.BackColor2 = Color.LightGreen
                    e.Appearance.Font = New Font("Tahoma", 10, FontStyle.Bold)

                ElseIf totalMinutes >= cautionThreshold AndAlso totalMinutes < warningThreshold Then
                    e.Appearance.BackColor = Color.Orange
                    e.Appearance.BackColor2 = Color.LightYellow
                    e.Appearance.Font = New Font("Tahoma", 10, FontStyle.Bold)

                ElseIf totalMinutes >= warningThreshold Then
                    e.Appearance.BackColor = Color.OrangeRed
                    e.Appearance.BackColor2 = Color.DarkRed
                    e.Appearance.Font = New Font("Tahoma", 10, FontStyle.Bold)
                    e.Appearance.ForeColor = Color.LightYellow
                End If
            End If
        End If

    End Sub

If you're going to use a standard DGV, you have something similar:

https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.cellformatting(v=vs.110).aspx

I don't know what your condition is, but be sure that it's "reachable" from that event handler.

Also see:

https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.cellformatting(v=vs.110).aspx

"A problem well stated is a problem half solved.” - Charles F. Kettering


Friday, December 15, 2017 11:21 PM | 1 vote

 Well,  the below example seems to work for me.  However,  if you don't set the DataGridView.DefaultCellStyle.Font to at least size 12 then as i said before,  the small font will be way to small to read.  Also, if you want to set the FontDialog to open to the Default Font,  it seems as though you have to create a new font of the DataGridView.DefaultCellStyle.Font to assign to the FontDialog when it opens or it will throw an exception.  I'm not sure why that happens though.

 Anyways,  i have tested this several times,  choosing several fonts,  and it seems to be working with the fixes i mentioned.

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DefaultCellStyle.Font = New Font(DataGridView1.DefaultCellStyle.Font.FontFamily, 11.25, DataGridView1.DefaultCellStyle.Font.Style)
        DataGridView1.Columns.Add("Column1", "Small Font")
        DataGridView1.Columns.Add("Column2", "Default Font")
        For i As Integer = 0 To 3
            DataGridView1.Rows.Add(New Object() {"Small-" & i.ToString, "Default-" & i.ToString})
        Next
        ResetColumnFontSize()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Using fd As New FontDialog
            fd.MinSize = 11
            Using fnt As New Font(DataGridView1.DefaultCellStyle.Font.FontFamily, DataGridView1.DefaultCellStyle.Font.Size, DataGridView1.DefaultCellStyle.Font.Style)
                fd.Font = New Font(fnt.FontFamily, fnt.Size, fnt.Style)
                If fd.ShowDialog(Me) = DialogResult.OK Then
                    DataGridView1.DefaultCellStyle.Font = fd.Font
                    ResetColumnFontSize()
                End If
            End Using
        End Using
    End Sub

    Private Sub ResetColumnFontSize()
        Dim fnt As Font = DataGridView1.DefaultCellStyle.Font
        DataGridView1.Columns(0).DefaultCellStyle.Font = New Font(fnt.FontFamily, (fnt.Size / 2) + 1, fnt.Style)
        DataGridView1.AutoResizeRows()
        DataGridView1.AutoResizeColumns()
    End Sub
End Class

 

 

If you say it can`t be done then i`ll try it


Saturday, December 16, 2017 2:36 AM

Ashidacchi,

Thank you! That's it! Thought I had tried every possible combination of arguments, but not that one. I found that  using your suggestion, I could adjust the size and keep everything else about the font in the specified column the same as the rest of the grid, like this:

   dg.Columns(3).DefaultCellStyle.Font =
         New Font(dg.Font.Name, dg.DefaultCellStyle.Font.Size * 5 / 6, dg.Font.Style)

There were so many combinations of possible arguments in the 13 "overloads" that I must have overlooked this one. I was about to give up!

Robert Homes


Saturday, December 16, 2017 1:00 PM

Robert,

We were in the middle of a storm yesterday afternoon so when my internet dropped out, I went ahead and shut everything down.

*****

Using a Dev grid isn't as difficult as I think you're making it out to be. One you've chosen the data source (the schema, really) it will add a BindingSource and bind the grid to that. You then control the data source of the BindingSource and it takes care of the rest.

If you have an idea for something that I could make, I'll do it two ways: With a standard DGV and with a Dev grid. I'll then build it and let you try it first-hand.

Food for thought...

"A problem well stated is a problem half solved.” - Charles F. Kettering


Sunday, December 17, 2017 8:13 PM

Robert,

I think you'll find this interesting if nothing else:

*****

Robert,

This is a way that you (and anyone else who’d care to) can compare a standard DataGridView with what you have: A DX DataGrid.

I have for many years had some “sample data” which is completely fake but does look to be real. As an example, have a look at this one which is for a hundred records:

 

http://www.fls-online.net/VBNet_Forum/SampleData/Sample_Data_100.xml

 

What I’ll present here will actually download 50,000 records as a CSV file. It will create a directory as a subdirectory from the ApplicationData directory that it creates. When we’re done with this, there’s a button which will delete the file and that directory, so it’ll be as if it never happened.

I have everything needed already embedded (there’s no installer) and zipped up here. You don’t need to have Dev Express or anything else; this is a demo program that I put together and it’s ready to run as soon as you extract the file from the zip.

When you open it, you’ll see this:

The first thing that you need to do will be to download the file. It’s only about 5 megs or so:

Note that the cancel button doesn’t actually cancel it, not really. This is using an FTP client and the transfer is FTPS(e). I have it set to resume so that if you pause it and go back to it, you’ll see that it picks up where it left off.

Once it’s completely downloaded, it will populate a standard DataGridView and take you to that display:

In the screenshot above, you’ll also notice that there’s a link in the navigation bar on the left to see the same data in a Dev DataGrid. My goal here was to show the data both in a standard DGV and using a Dev grid. If you’re interested, you can have a look at the code here:

 

http://www.fls-online.net/VBNet_Forum/12-17-17/DemoDataGrids.htm

 

What you won’t see in that code is anything about the data itself nor anything about the logic behind it. This goes back what I suggested the other day: Keep the data and the logic out of the form’s code; you don’t want those two things to be coupled.

In the code shown in the link above, there are calls to methods/properties/eventargs in a class library which is doing all of this. Since I’m not adding anything (with the UI) nor am I deleting anything with the UI, the logic is obviously simple here.

Before going too far with any of this, have a look at what’s in that library shown here. There are other classes also but those are all ‘helper’ classes; those two classes shown are the main ones.

You asked me several days ago about how I can have data but no database; on a simple basis like this, a database isn’t needed – encapsulation is all that’s needed. That along with a collection of the encapsulated data is the only thing required here (keep in mind that nothing is being added or deleted in this demo – so the logic is very simple).

The “data” is shown on the left in the illustration of the class diagram. The class named “Person” is what each record consists of and in this case there are 50,000 of them so obviously we have to have a repository for them. You’ll see a method there named “LoadFromCSV” and it has an access level set as Friend. The only other class in this entire thing which can work with “Person” is the other class that you see in that library: “PeopleData”.

I set that up to be the ‘administrator’ of all of this. It has the FTPS downloader and if you’ll look, you’ll see a property called “People” which is a collection (an IEnumerable) of “Person”.

There’s also a separate property which is a BindingSource for the DGV. I don’t need it for the Dev grid; Dev has its own but I need it for the DGV because of something that I’d otherwise be missing: Mapping.

The Dev grid has mapped the IList (the IEnumerable(Of Person) here) with the field name and the caption and any other settings that I have but the setup for the DGV is totally up to you in code. If I’d given the DGV the Dev BindingSource it would work, but the captions would be all wrong (for example, it would show “FirstName” instead of “First Name”.

For that reason, in the “Person” class I have a method which will create a DataTable and everything is set up from that. I then have a BindingSource’s .DataSource set to that DataTable and that’s what the DGV is bound to.

I hope that’s not confusing…

 Have a look at both grids; they both use the same data. Even though it’s unlikely that you’ll ever want to load 50,000 records at once, I’m doing that here for reason which I’ll show shortly. When you see the Dev grid:

You’ll see a “Find” box and a “Group By Column” at the top. I’m not being unfair to the DGV; both of these are standard features in a Dev grid unless you disable them. The only thing I’ve done is to set them up but they’ve always been there.

One thing that’s confusing both to end users and developers alike is how the “Find” works, at least when it comes to phrases which have more than one word. You can set the “Find” to only look in certain columns but by default it will look in all columns so for this one, it’s looking through 50,000 x 8 = 400,000 fields but you’ll see that it does that pretty quickly.

To explain more about multiple words/terms in a “Find”, I’ll have it look for New Jersey in the following:

Notice that it did find New Jersey but it also found New York and New Mexico. Assuming that’s not what the user intended, explain to them that the default (when there are two or more words/phrases) is a logical OR.

If they want a logical AND (which makes sense that they would) then shroud the phrase in double-quotes and then have it look again:

That’s more likely what they were looking for.

 

 

Continued on the next post…

"A problem well stated is a problem half solved.” - Charles F. Kettering


Sunday, December 17, 2017 8:13 PM

Continued from the previous post…

 

 

Continuing now,

As for grouping, this is where Dev really shines.

Keep in mind that there are 50,000 rows @ 8 fields each. I have this set up to only allow grouping on the column for “State” and the column for “City”. I’ll first group by State. I grab the column header and s-l-i-d-e it into the group column:

When I let go, pretty quickly it ripples through all of those records, grouping each by state name:

Now I’m going to continue the grouping strategy: I want them grouped first by state, then sub-grouped by city. I’ll do the same as before but this time, I’ll direct it to be a sub-group of state:

It’s done pretty quickly as you’ll see:

To “ungroup”, let them know that they can slide those headers back (actually, they can insert them anywhere in the column headers unless you disable that) or they have a built-in context menu – just right-click the column header and click on “UnGroup”:

Finally then, we’re done experimenting and you’re ready to delete it, click the button in the menu bar to let it delete the data file and the directory that it’s in:

Following that, close the program and just delete it; it’ll be totally gone.

I’m not at all meaning to knock using a standard DGV, but even though the Dev control is more complex, you can give your users a lot just by setting a few things up. It’s not hard, really, and if you run into a bind then ask me here or ask Dev.

 

 

If you have any problems with it, let me know and I look forward to your thoughts about it all. :)

 

"A problem well stated is a problem half solved.” - Charles F. Kettering