Click here to Skip to main content
15,880,469 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,
I'm required to clone Windows Notepad but I've run into a bit of a problem. The windows note pad has a status bar that indicates the current line and column of the blinking cursor. I've been doing some research and I ran into the following code, to which I made some changes:

VB
Public Sub UpdateStatusBar()
       Dim index As Integer = TextBox1.SelectionStart
       Dim currentLine As Integer = TextBox1.GetLineFromCharIndex(index)
       Dim currentColumn As Integer = index - TextBox1.GetFirstCharIndexFromLine(currentLine)

       tss1.Text = "Line " + (currentLine + 1).ToString + ", column " + (currentColumn + 1).ToString
   End Sub


I call this sub on textbox.text_changed event and it works perfectly while I'm writing. I also call it on textbox_keydown so as to update the status bar when I move around the control with the arrow keys. But here it gets messed up. When I move around the text the line and column values are always wrong. I tried playing around adding 1 or 2 or 0 to the value under say for example key.left pressed but i haven't figured out an algorith the represents exactly what line and column the cursor is in. I need it to work just like the windows note pad. Ideas? anybody?

I also think it would be fairly easier to do if the blinking cursor position could be retreived somehow, but I don't know if that's possible. I haven't found anything on that subject either.

Thanks
Posted
Updated 25-Oct-11 21:21pm
v2

The problem is not that you need to offset anything, it is that you are doing it at the wrong time. This is a bit difficult to get your head round, but fundamentally you either need to know how the .NET framework (and Windows) works a bit better, or change the way you are doing things.

The easiest way around this is to accept that the user does not need to have every little change updated on the status line immediately. In fact, this can slow down the whole application. Do you think the user would notice if his cursor position was updated 4 times a second? Ten times? The first, yes, maybe, the second? No. Not even slightly.

Normally, I wouldn't recommend a timer, but sometimes they are the most sensible way to go, and this is such a case. Add a timer to your application. Set the Interval to 100 (i.e. 1/10 second) and handle the Tick event. In the tick event, update your status line. Remove all other update code. Now, like magic, your code above will work!
 
Share this answer
 
Comments
Vic91 26-Oct-11 4:09am    
Thanks! It makes sense but I just tried it and I have some errors. I've never used timers and I get this error:
"Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on"
Could you please tell me how I should fix this?
OriginalGriff 26-Oct-11 4:17am    
You have presumably created the timer in your code - but not in the form load event or similar. Somehow, you have created the timer on a non-UI thread (a background worker, or similar?) and it can't access the status bar. Move the creation code, or add the timer via the VS designer.
Wayne Gaylard 26-Oct-11 4:18am    
Nice. Out of the Box thinking - I like it!
OriginalGriff 26-Oct-11 4:32am    
You have to with this kind of thing, because it is difficult to explain what is happening (event / display / textbox order of execution) without pictures or some arbitrary comparison to card games! Plus, you can't see at which point the OP's eyes start to glaze over... :laugh:
Vic91 26-Oct-11 4:24am    
Thanks a lot! It works perfectly!
The numbers are wrong because you have Word Wrap turned on. A line in a TextBox is not the visible lines on the screen. A line is terminated by hitting Enter.

Notice in Notepad that if View->Word Wrap is turned on, the Status Bar is turned off and it's probably for this very reason.

The only time you see the Status Bar enabled, or have the ability to enable the Status Bar, is if Word Wrap is turned off. Then, and only then, are the line number counts accurate.
 
Share this answer
 
Here guys! If you're getting errors then do this. Add a StatusStrip and in that add a ToolStripStatusLabel. Add a Timer, enable it and and set 1 as its interval. Double Click the Timer and Write this Above Code Except the First and the Last Line. Also, change tss1.text to ToolStripStatusLabel1.text. Hope this Helps!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900