Solved

.Net Windows Forms Button Size question

Posted on 2011-09-09
7
393 Views
Last Modified: 2012-05-12
How, given input text and font, do I calculate a button's size? For Labels and Textboxes I use the TextRenderer.Measurestring to get the text size, then set the control's ClientSize property. The control's Size property is automatically set a little larger by the system and everything works fine. However, buttons dont do this and the text gets cut off when the button is displayed.

Currently I am fudging, adding an amount to the text height and width that I found by trial and error. It doesnt work perfectly but is OK. Is there a correct way to do this calculation.

I am using framework 4, Windows 64 bit.
0
Comment
Question by:MikeBroderick
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 18

Expert Comment

by:lludden
ID: 36511335
You can use the MeasureString method

Here is the code sample from MSDN:
Private Sub MeasureStringMin(ByVal e As PaintEventArgs)

    ' Set up string.
    Dim measureString As String = "Measure String"
    Dim stringFont As New Font("Arial", 16)

    ' Measure string.
    Dim stringSize As New SizeF
    stringSize = e.Graphics.MeasureString(measureString, stringFont)

    ' Draw rectangle representing size of string.
    e.Graphics.DrawRectangle(New Pen(Color.Red, 1), 0.0F, 0.0F, _
    stringSize.Width, stringSize.Height)

    ' Draw string to screen.
    e.Graphics.DrawString(measureString, stringFont, Brushes.Black, _
    New PointF(0, 0))
End Sub

Open in new window

0
 

Author Comment

by:MikeBroderick
ID: 36511398
Tried it, doesnt work. Graphics.MeasureString doesnt calculate the string size correcly for display devices. I use the TextRenderer.MeasureText method instead. it works correctly.

The problem I am having is the fact that when you set a button's client size, the sze is not adjusted for any nonclient stuff the way labels and textboxes do.
0
 
LVL 15

Accepted Solution

by:
x77 earned 500 total points
ID: 36512428
Windows Controls uses GDI, then you need eval using Gdi functions.

.Net uses GDI+ and DrawString has some diferences with Gdi TextOut, also on Font Size

The easy solution is create the button an Layout it:

Private btn As New Button With {.AutoSize = True, .visible = False}

    Public Sub EvalSizeButton(ByVal Font As Font, ByVal Txt As String)
        Button1.SuspendLayout()
        btn.Font = Font
        btn.Text = "Esto es una Prueba"
        btn.Size = New Size(0, 0)
        btn.ResumeLayout()
        Debug.Print(btn.Size.ToString)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
       Me.Controls.Add(btn)
       EvalSizeButton(New Font("Arial", 16), "Prueba")
       EvalSizeButton(New Font("Arial", 10), "Prueba 2")
       Me.Controls.Remove(btn)
    End Sub

Open in new window

0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 15

Assisted Solution

by:x77
x77 earned 500 total points
ID: 36512440
Sorry, replace Line:
   Button1.SuspendLayout()
with
   btn.SuspendLayout()
0
 

Author Comment

by:MikeBroderick
ID: 36513169
Thank you, but this didnt work either. The AutoSize = True line makes the button display correcly. I do not see the need for any of the suspend, resume, or size lines. Please let me know if I am missing something.

The problem with using AutoSize is I need the button's overall size so I can place other objects on the form near each other and have correct spacing. With AutoSize = True, I now dont know the actual button size.

This seemed to work. It turns AutoSize on and then off, recording then setting the  height/width:

   
Private Shared Sub BldButton(ByRef inButton As Button, ByVal inParent As Object, _
                       ByVal inText As String, ByVal inFont As Font, _
                       ByVal inLoc As Point)
        Dim ww, hh As Int32

        inButton = New Windows.Forms.Button
        inButton.AutoSize = True
        inButton.Parent = inParent

        inButton.Font = inFont
        inButton.Text = inText
        inButton.Location = inLoc

        ww = inButton.Width
        hh = inButton.Height
        inButton.AutoSize = False
        inButton.Height = hh
        inButton.Width = ww

    End Sub

Open in new window

0
 
LVL 15

Expert Comment

by:x77
ID: 36513295
Note I do´nt suggest you to set your button autosize.

In suggest use a invisible button to eval size, then set the size to your control or draw the control with this size.

I test the evalsize method and works fine.
I SuspendLayout / resumeLayout on an auxiliar control used only to eval size.

I think you are adding / resizing controls.
0
 

Author Comment

by:MikeBroderick
ID: 36513320
Sorry I didnt understand. The DebugPrint prints the correct button size, which is what I want. Thank you.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

737 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