Solved

Detect if all text in TextBox is visible

Posted on 2006-06-09
8
667 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
[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
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
Major Incident Management Communications

Major incidents and IT service outages cost companies millions. Often the solution to minimizing damage is automated communication. Find out more in our Major Incident Management Communications infographic.

 

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
 
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 our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

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

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

729 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