How to programmatically measure string pixel width in ASP.NET?
Asked Answered
E

8

11

How do you get the size of a string? In Windows Forms it's easy, I just use graphics object and then MeasureString function. In ASP.NET I'm not sure how to do this.

Egan answered 5/4, 2011 at 14:58 Comment(3)
Are you trying to get the pixel size of the string on screen or the length of the string in characters?Givens
I'm trying to get the pixel width so i can programmatically size a dropdownlist to the largest stringEgan
If you're using ASP.NET to create a Web Application...this is going to be a little more difficult. Are you trying to make all inputs on the page the same uniform width? If not, the browser will automatically size things for you as long as you don't specify a width.Givens
C
15

Like Tom Gullen is saying. You can just create a bitmap and messure the string. I have this code I use to find the width/length in pixel. Just change the font and size.

// Bitmap class namespace:
using System.Drawing;

...

private float GetWidthOfString(string str)
{
    Bitmap objBitmap = default(Bitmap);
    Graphics objGraphics = default(Graphics);

    objBitmap = new Bitmap(500, 200);
    objGraphics = Graphics.FromImage(objBitmap);

    SizeF stringSize = objGraphics.MeasureString(str, new Font("Arial", 12));

    objBitmap.Dispose();
    objGraphics.Dispose();
    return stringSize.Width;
}

Just wanted to show an example.

Ceratoid answered 28/9, 2012 at 8:1 Comment(4)
Thanks. I used asawyer's suggestion to find length using linq and then passed in the longest string to your function and it worked out great. Also, I adjusted the font type and weight to my needs.Egan
Here is another alternative using jquery. jquery exampleEgan
I have tried this solution in my blazor application. I can't find the Bitmap class in System.Drawing namespace. Is there any other dependencies needed for Bitmap and Graphics class?Shrug
@KesavanSubramaniamChe Don’t think Blazor has Bitmap, but it other image libraries like ImageSharp. I have not used it myself.Ceratoid
D
3

String.Length

Returns the length of the string (number of characters).

C#

string MyString = "Stack Overflow String";
Response.Write(MyString.Length);

VB.net

Dim MyString As String = "Stack Overflow String"
Response.Write(MyString.Length);

MSDN Reference

http://msdn.microsoft.com/en-us/library/system.string.length.aspx

Physical String Size Serverside

I'm not sure why so many people are apparently determined to put forward the idea that it is 'flat out impossible' to do this server side, it isn't. You just need to be a little bit creative, and be willing to do a lot of testing.

There is no native function I know of to measure the pixel dimensions of a string. You can achieve it in the following ways. Note you need to know:

  • The font family
  • Font size
  • Container dimensions (for when the text wraps lines)
  • Any other CSS rules such as word spacing are going to make the calculation a lot less accurate and more complex. Try and avoid it if accuracy is important.

1. Render it to an image and measure image size

Draw the text to a bitmap, and then measure it. This should be reasonably exact.

2. Use a fixed width font

If you are using a fixed width font and the text doesn't wrap, you can simply multiply its width by the number of characters.

3. Rough estimation

You could get a reasonably rough estimation on non fixed width fonts by picking some arbitrary character width number and multiplying it by total characters. Depends how accurate you want to be.

Doormat answered 5/4, 2011 at 15:1 Comment(17)
i tried that before however i then have to mulitply that by an average pixel width for a text character which is a little bit sketchy.Egan
fyi the client has control and can override and throw all these calculations off. The only sure way is to render into a temporary span and use client functions to measure that.Superfuse
@Asawyer, and what if the client has Javascript disabled? You have to make a compromise at some point. If the font is specified as being 12px and Courier New, you can pretty much safely assume that is how it is going to be rendered. He asked for a server side solution specifically, that is what I have tried to provide him with.Doormat
@Tom If the client doesn't have scripting enabled (I often do not) they get a substandard experience on the web page. I don't see a need to code a somewhat slow/resource intensive bitmap rendering scheme to handle that case, when theres a decent chance your answer is wrong anyways, and you literally have no way of knowing (Besides an angry email I guess) when and where you get it horribly wrong. This is just my opinion. :)Superfuse
@Asawyer interesting point of view. Your assumption that it will be slow/resource intensive doesn't really carry any weight. Also, I've done similar things before, I've rendered text from a browser designer to a bitmap and it took a bit of effort and testing but it works just fine, no complaints yet ;-) So I know it can work and does work fine. I've no idea why you would turn Javascript off, seems paranoid to me, but if people do then you should be designing the pages with progressive enhancements so they don't have substandard experiences.Doormat
I could try and call a javascript function as indicated by asawyer's link. Then there's the quick and dirty way of just meas. the length and multiplying. I will experiment with the methods posted here for now. Thanks to everyone who contributed, i will check periodcally for more answers.Egan
@Tom: I think you're forgetting about browser scaling (and zoom) level. A 16px font may be a completely different size on your machine and my machine depending on browser settings.Argus
@Tmax pick what's best for you, experiment, and remember that nothing in computing is really impossible at the end of the day. Good luckDoormat
@Tom It's slower then not attempting it. Got ya there. Joking aside, it's a somewhat relative term. Maybe you have a killer server and everything is cool. I expect something like that would not scale very well as your hit rate increases, but i'm just speculating really. I once wrote a page that rendered barcodes as bitmaps to the client so I know it's not anything insanely slow or impossible. Just in this case I'm just not seeing the benefits outweighing the cost. Again this is all just my opinion.Superfuse
@Asawyer, server side is quicker for the client. Client side is quicker for the server. So criticising one solution for being slower than another is meaningless because we don't know what tmax wants, or what the purpose of the code has, but the question specifically asked for a server side solution. People searching on Google are going to be looking for a server side solution when they view this question.Doormat
@Maybe you would be so kind to show us some specific CSS and code (and its results). For a simple test I tried right now seems to suggest various browsers can and do render identical HTML differently. See i56.tinypic.com/143mdl3.png The only valid answer to this question is – you cannot do that server-side, and do not want to – attempts to do that only indicate another problem is behind (like in this case, forcing a dropdownlist to have a specific width, and then overriding the width with dynamically computed maximum width, which would be the default).Otto
@Otto I'm not going to go through my code and provide results sorry it'll just take too long. It works, I've tested it in IE6+, Chrome and FF and it's pixel perfect when rendering text to an image. What's frustrating is that no where in my answer did I phrase it saying "This will guarantee a perfect solution", I've been careful to phrase it to suggest you are likely to come across inaccuracies, whilst other answers in this question are ready to criticize it as being an impossible task that no programmer has ever been able to overcome, and that a client side solution is the only way.Doormat
@Mormegil, also you, like asawyer, are going to need to qualify such assumptions as 'the only valid solution'. It's baselessDoormat
Look, I dont understand why we are arguing over this, you provided your solutions, I provided mine. I have tried to be as accurate as I could, and answer the question as faithfully as possible. And I have pointed out in other peoples questions that their assumptions of it being impossible are wrong. That is all.Doormat
@Tom Gullen - “Often, people who need technical help have a high-level goal in mind and get stuck on what they think is one particular path towards the goal. They come for help with the step, but don’t realize that the path is wrong.” [ESR]Otto
@Mormegil, I never said the client side solution was wrong. I encourage and am interested in alternative routes, see my comment 'it's good you have pointed out an alternative solution'. But if I see blatant misinformation being spread, such as server side is impossible, I am going to correct it for the benefit of people searching for a server side solution in the future. All these criticisms of a server side solution are just assumptions made without any knowledge of the context the question asker is applying the code in.Doormat
@Tom Was an interesting thought exercise at least. :)Superfuse
S
3

If you are using JQuery, see this answer

Determine Pixel Length of String in Javascript/jQuery?

I'm sure if not you can work something similar.

Superfuse answered 5/4, 2011 at 15:4 Comment(5)
For the downvoters - he mentions "graphics object and then MeasureString function." ie he wants the pixel width of the rendered string. The only way to do that is client side, and the link provided shows a method for determining this.Superfuse
You'll have to resize the dropdown on client load, look up the body load event, you'll want to determine size and then resize your list there.Superfuse
"The only way to do that is client side", that is false I'm afraid. Although it's good you have pointed out an alternative solution.Doormat
ok how about "The only way to be relatively accurate is client side"? :)Superfuse
How about, "Here is an alternative solution that may fit your needs better".Doormat
W
1

The following method will provide the size of a String rendered in a given font:

private RectangleF sizeOfString(string text, Font font)
{
    GraphicsPath path = new GraphicsPath();
    path.AddString(text, font.FontFamily, (int)font.Style, font.Size, new Point(0, 0), new StringFormat());
    return path.GetBounds();
}

You could then use this to get the width as follows

float width = sizeOfString("Hello World", someFont).Width;
Whitesell answered 11/8, 2017 at 10:42 Comment(1)
this is good, however, the font size needs to be in pixels, use: Font.SizeInPoints / 72 * User32.GetDpiForWindow(Handle) and lookup how to invoke getdipforwindow elsewherePussyfoot
C
0

You can use the Length property on a string as follows:

http://www.dotnetperls.com/string-length

Cavein answered 5/4, 2011 at 15:0 Comment(4)
FYI, I'm not a Windows programmer. Question tags did not reflect this.Cavein
no the answer is fine, someone in this question is down voting all the other answers for no apparent reason apart from their own gain by the looks of things. I've +1 you to negate it.Doormat
Thanks Tom... I haven't had the coffee yet ;-)Cavein
I guess it should be obvious (at least now) the question asks for pixel width of text, not its length in characters.Otto
O
0

It is a completely impossible thing to do on server side (assuming by “ASP.NET”, you mean web pages created using ASP.NET”). ASP.NET outputs HTML, which is a markup language interpreted and rendered by a browser on the client. The same HTML code can be displayed on various devices, in various browsers, using various installed fonts, etc., resulting in grossly differing display.

Your ASP.NET site, running code on the server, does not know which font, what resolution, etc. your client uses. The only theoretical way this could be done would be to run client-side code (e.g. JavaScript, Silverlight, Flash, …) to report back to the server. However, this would be quite difficult.

Generally, you do not need to do that, you do not want to do that.

Otto answered 5/4, 2011 at 15:5 Comment(1)
It's not completely impossible sorry.Doormat
E
0

@Tom Gullen, @asawyer

This is my temporary solution and it seems to be working for now. fyi, my project happened to be a asp.net application with many dynamic interfaces involved in it (thats another story). At anyrate my short term solution is posted below. Im acually using a modalpopupextender (with listbox) on the fly when the user clicks a textbox (custom combobox). The ajax combobox doesn't work very well especially when there is many of them and you can't set the dropdown width on a dropdownlist.

Friend Function ResizePopup(ByVal sender As Object, ByVal standardwidth As Integer) As Integer
    Dim lst As ListBox = CType(sender, ListBox)
    Dim itemlength As Single = 0

    'get longest string length
    For Each item As ListItem In lst.Items
        If item.Text.Length > itemlength Then
            itemlength = item.Text.Length
        End If
    Next

    'set a general multiplier
    Dim newWidth As Integer = itemlength * 7

    'compare to width of control, if larger, then use value else return control width
    If newWidth > standardwidth Then
        Return newWidth
    Else
        Return standardwidth
    End If

End Function
Egan answered 5/4, 2011 at 17:2 Comment(2)
finding the longest string imperatively with linq is very easy dim strings = new List(of string)(new string(){"a","aa","aaa"}) dim longestString = strings.OrderByDescending(function(s) s.Length).Take(1)Superfuse
Uh be sure to check and see if any elements exist first, or change Take to SingleOrDefault and do a Null check.Superfuse
Q
0

@Eystein Bye's solution, made slightly cleaner with usings:

using (Bitmap objBitmap = new Bitmap(5000, 200))
{
     using (Graphics objGraphics = Graphics.FromImage(objBitmap))
     {
          SizeF stringSize = objGraphics.MeasureString(txt, new Font("Arial", 12));
          return stringSize.Width;
     }
}
Quantifier answered 8/4, 2018 at 16:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.