Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Need to add a 'Ruler' to a .Net textbox (windows forms application)

Posted on 2012-03-19
20
Medium Priority
?
1,586 Views
Last Modified: 2012-03-30
Hello,

I need to add a ruler to a textbox in my windows forms project in Visual Studio 2008. The textbox will not accept anything more than 125 characters, hence the ruler above it should go from 0 to 125 with the 10's highlighted.

                     10                  20
|||||||||||||||||||||||||

thats a rather awkward representation of what I want, but you get the idea. I imagine that this ruler will depend somewhat on the font the textbox will use as well.

Thanks in advance.
0
Comment
Question by:CodeWrangler
20 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37739780
Would it be simpler to have a label next to the box whose text updated with the number of characters remaining (or consumed), like you typically see on the web?
0
 

Author Comment

by:CodeWrangler
ID: 37739794
Hi Kaufmed.

Yes, I agree that it would, however, design requirements are design requirements and I need a ruler on top of the textbox :)
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37739821
Are you restricting your available font's to monospaced fonts? I don't know that you can guarantee a proportional scale for non-monspaced fonts. A "w" in a non-monspaced font is going to be much wider than an "i" in that same font.
0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37739826
...or does the ruler just need to span the width of the TB, disregarding the actual width of the text within the TB?
0
 

Author Comment

by:CodeWrangler
ID: 37739854
Yes, monospaced fonts only. The ruler needs to match the text as closely as possible.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 37740010
With the Font set to "Courier New" at a mere 8 Points, the TextBox needs to be about 885 pixels wide to accommodate 125 characters!  Is that acceptable?...
0
 

Author Comment

by:CodeWrangler
ID: 37740245
Yes it is. If need be I can have 2 textboxes, and hence 2 rulers. However, at the moment all I need to know is how to create a ruler above a textbox.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37740539
For simplicity (I think), you could create a UserControl that contained a TextBox and a Label. The Label would be used to draw the actual ruler, and it would be positioned just above the TextBox. I started playing around with this code, but it is nowhere near perfect. You will need to play with the math a bit, but I think it would give you a start.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace _27639257
{
    public partial class RulerBox : UserControl
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RulerBox"/> class.
        /// </summary>
        public RulerBox()
        {
            InitializeComponent();
            this.label1.Left = this.textBox1.ClientRectangle.Left;
        }

        /// <summary>
        /// Handles the FontChanged event of the RulerBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void RulerBox_FontChanged(object sender, EventArgs e)
        {
            this.textBox1.Font = this.label1.Font = this.Font;
        }

        /// <summary>
        /// Handles the Paint event of the label1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        private void label1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            SizeF sizeofW = g.MeasureString("W", this.Font, 0, StringFormat.GenericTypographic);
            float halfWidth = (sizeofW.Width / 2F);
            float halfHeight = (sizeofW.Height / 2F);

            for (float i = (halfWidth + (this.textBox1.Bounds.Left - this.textBox1.ClientRectangle.Left)), x = 1; i < this.ClientRectangle.Width; i += sizeofW.Width, x++)
            {
                if (x % 10 == 0)
                {
                    g.DrawString(x.ToString(), this.Font, Brushes.Black, (i - halfWidth), 1);
                    g.DrawLine(Pens.Black, i, halfHeight + 5, i, this.label1.ClientRectangle.Height);
                }
                else
                {
                    g.DrawLine(Pens.Black, i, halfHeight + 8, i, this.label1.ClientRectangle.Height);
                }
            }
        }

        /// <summary>
        /// Performs the work of setting the specified bounds of this control.
        /// </summary>
        /// <param name="x">The new <see cref="P:System.Windows.Forms.Control.Left"/> property value of the control.</param>
        /// <param name="y">The new <see cref="P:System.Windows.Forms.Control.Top"/> property value of the control.</param>
        /// <param name="width">The new <see cref="P:System.Windows.Forms.Control.Width"/> property value of the control.</param>
        /// <param name="height">The new <see cref="P:System.Windows.Forms.Control.Height"/> property value of the control.</param>
        /// <param name="specified">A bitwise combination of the <see cref="T:System.Windows.Forms.BoundsSpecified"/> values.</param>
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            base.SetBoundsCore(x, y, width, this.textBox1.Height + this.label1.Height, specified);
        }

        /// <summary>
        /// Handles the Resize event of the RulerBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void RulerBox_Resize(object sender, EventArgs e)
        {
            this.label1.Width = this.textBox1.Width = this.Width;
        }
    }
}

Open in new window

0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37740553
Here's what the above looks like in my designer:

Screenshot
0
 

Author Comment

by:CodeWrangler
ID: 37743174
Kaufmed, that is a novel idea!!

Can you show me the code where you are actually using the class RulerBox in Form1?
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 37743233
kaufmed created a (really nice) user control. if you add it to your project and compile your project, you should see the new control into your toolbox. just drag-and-drop it on your form
0
 

Author Comment

by:CodeWrangler
ID: 37743324
ah yes... my bad. Somewhat of a .Net noob here. I will continue to try this out and report back.

Kaufmed.. again, that is a truly great suggestion!
0
 

Author Comment

by:CodeWrangler
ID: 37755437
Kaufmed, may I have the files for the control u created? I cannot seem to get the code to function quite like your screenshot.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37755558
It's what I posted above ( http:#questionCommentsViewInlineCode20-37740539-1 ). You need to add a new UserControl (Project->Add New Item->User Control), then add a Label and a TextBox to the UserControl. You can paste the code above into the code-behind for the UserControl. Note:  You need to change the namespace to match your project.
0
 

Author Comment

by:CodeWrangler
ID: 37755605
Appreciate all your help.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37755619
If you still have problems, I'll attach a complete project so you can compare.
0
 

Author Comment

by:CodeWrangler
ID: 37769235
Thanks, Kaufman. Unfortunately I haven't been able to test the code again. Probably won't get the chance until next week. If it is not too much trouble could you post the project file, it will make things a lot easier for me.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37769296
Sure. I can't remember which machine I created it on. If I can't track it down, then I'll recreate it. I'll have something up for you later tonight.
0
 

Author Comment

by:CodeWrangler
ID: 37769342
No rush whatsoever. Thanks a ton Kaufmed!!
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 2000 total points
ID: 37774279
Sorry for not posting it last night. On the bright side, I did find the original code  = )

You can download the zipped project from here: https://filedb.experts-exchange.com/incoming/ee-stuff/8237-27639257.zip
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
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.
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

783 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