Solved

Detect if all text in TextBox is visible

Posted on 2006-06-09
8
652 Views
Last Modified: 2012-06-21
Wish to change the background color of a TextBox if the text is not all displayed.
Wish this to work with Multiline True or False, as well as for different client rectangle sizes, and different font sizes and bold/italic etc.

Purpose is to let user know that there is more text than is shown.

Tried this solution, but it is not exact.

' Control inherits from TextBox
Protected Overrides Sub OnTextChanged (ByVal e as System.EventArgs)
   MyBase.OnTextChanged(e)
   ' If it all fits, then background color is Window, else Control
   Dim clientWidth as Integer = ClientSize.Width
   Dim clientHeight as Integer = ClientSize.height
   Dim grfx as Graphics = CreateGraphics
   Dim fudgeWidth as Double = grfx.MeasureString(" X", Font, Integer.MaxValue)
   Dim actualSizeF as SizeF = grfx.MeasureString(Text, Font, clientWidth + fudgeWidth)

    If actualSizef.Height <= clientHeight then
        BackColor = Drawing.SystemColors.Window
    Else
        BackColor = Drawing.SystemColors.Control
    End If

    grfx.Dispose
End Sub      
   
' This works most of the time, but would like it to work all the time.
' Does TextBox use vanilla DrawString, or does it use some proprietary method of drawing text?
' Alternative is to build my own TextBox from scratch, but that doesn't sound pleasant!

Thank you,
Brother Bill
0
Comment
Question by:brotherbill999
8 Comments
 
LVL 28

Expert Comment

by:strickdd
ID: 16870651
In a multiline textbox you won't have to worry about "letting the user know" because it will display scroll bars. As for a single-line textbox the is no EXACT way to do this because all browsers interpret the textbox "columns" property slightly differently. The best thing to do would be to do a textbox.Text.Length and see if it is greater than the column numbers, that will typically mean there is more text, but not always.
0
 

Author Comment

by:brotherbill999
ID: 16871216
Clarification: This is a Winforms TextBox, not ASP.NET.
A single line textbox may have an overflow of data, without visually indicating so.
A multi-line textbox may not have scroll bars, therefore the user may not be aware of additional data.

Thus, the reason for the question.  It would be nice to provide a background color difference if some data is hidden.
0
 
LVL 5

Expert Comment

by:AdGroot
ID: 16872031
Try this

          if (textBox1.PreferredSize.Width > textBox1.Size.Width)
            {
                textBox1.BackColor = Color.Red;
            }
            else
            {
                textBox1.BackColor = Color.Blue;
            }
 

Ad
0
 

Author Comment

by:brotherbill999
ID: 16872695
Hi AdGroot.  
Your solution is *close* for Multiline = False, but it displays overflow color, even when text fits.
Your solution doesn't work at all for MultiLine=True.

Would appreciate other suggestions...
Brother Bill
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 2

Accepted Solution

by:
shy_talk earned 500 total points
ID: 16873308
Just to add to the confusion...

I got this working after a fashion. Dont' gush with gratitude. The code is crap,  but it worked OK at first glance with single line textbox and another invisible textbox of the same size on the same form. I know for a fact that this will not work as it is with multiline, but who knows, a genius like yourself may well be able to succeed where a sucker like me has failed. Good luck.

   private void textBox3_TextChanged(object sender, EventArgs e)
      {
         
         TextBox txt = (TextBox)sender;
       
  // Just bulletproofing
         if (textBox4.Size != txt.Size)
         {
            textBox4.Size = txt.Size;
         }

// Copy the text to the invisible TextBox
         textBox4.Text = txt.Text;
         Application.DoEvents();

// Sample the index at the left of the box
         textBox4.SelectionStart = 0;  
         c1 = textBox4.GetCharIndexFromPosition(new Point(2, 2));

// Try to scroll the box
         textBox4.SelectionStart = txt.Text.Length;   //textBox4.Text.Length;
         c2 = textBox4.GetCharIndexFromPosition(new Point(2, 2));
       
// Well, here goes sod all...
         if (c1 != c2)
         {
            txt.BackColor = Color.Pink;
         }
         else
         {
            txt.BackColor = Color.White;
         }
      }

// You did ask for suggestions, not solutions...
0
 

Author Comment

by:brotherbill999
ID: 16875056
Great job shy_talk.  Just streamlined your solution, and figured out the Multi-line solution.  Just count the lines used, vs. available lines.  Anyway, here is the documented source code.  Thank you all.
Thus, the user can be informed, via background color, that there is hidden text in a TextBox.



    ' Inherited from TextBox, so Me is a TextBox
    Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
        MyBase.OnTextChanged(e)
        ' If it all fits, then background color is Window, else Control
        If FullyVisible(Me) Then
            BackColor = Drawing.SystemColors.Window
        Else
            BackColor = Drawing.SystemColors.Control
        End If
    End Sub

    ' This is the work horse...
    Public Function FullyVisible(ByVal txtBox As TextBox) As Boolean
        If txtBox Is Nothing Then Throw New ArgumentException("FullyVisible: txtBox may not be Nothing")
        Dim Result As Boolean
        If txtBox.Text.Length = 0 Then
            ' No matter how small the textbox is, you see all that there is, that is Nothing
            Result = True
        ElseIf txtBox.Multiline = False Then
            ' Create a copy of original text box, and copy key attributes
            Dim txtBox2 As New TextBox
            Dim pt2_2 As New Point(2, 2)
            txtBox2.Font = txtBox.Font
            txtBox2.Size = txtBox.Size
            txtBox2.Text = txtBox.Text
            ' c1 is char index 2 pixels from left, typically 0
            txtBox2.SelectionStart = 0
            Dim c1 As Integer = txtBox2.GetCharIndexFromPosition(pt2_2)
            ' c2 is char index 2 pixels from left, after scrolling to make last character visible
            txtBox2.SelectionStart = txtBox2.Text.Length
            Dim c2 As Integer = txtBox2.GetCharIndexFromPosition(pt2_2)
            ' If character indexes are equal, then you see all there is to see
            Result = (c1 = c2)
        Else
            ' MultiLine = True
            ' Client Height is the maximum vertical area inside the box where text may be written, excluding margins
            Dim clientHeight As Integer = txtBox.ClientSize.Height
            ' Line Height is number of pixels for each row, including white space
            Dim lineHeight As Integer = Math.Ceiling(txtBox.Font.GetHeight)
            ' Max Lines is number of visible lines of text
            Dim maxLines = Math.Floor(clientHeight / lineHeight)  ' Maximum rows that can be shown

            Dim len = txtBox.Text.Length
            ' Find which line (origin 1) that the last character is on
            Dim line1 As Integer = 1 + IIf(len = 0, 0, Me.GetLineFromCharIndex(len))
            ' If its within the max lines, its fully visible, else there is some hidden text
            Result = (line1 <= maxLines)
        End If

        Return Result
    End Function
0
 
LVL 2

Expert Comment

by:shy_talk
ID: 16882148
Well, what a pleasant surprise! Two heads and all that. Great little puzzle. Thanks for the points, bro'.
0
 

Author Comment

by:brotherbill999
ID: 16884895
When making the project Option Strict, noticed that certain variables need to be cleaned up, such as maxLines and len.  I'll post that at a later time.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

760 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now