On a TextBox I can calculate the number on lines with the following code:
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged linecount = SendMessage(TextBox1.Handle.ToInt32, EM_GETLINECOUNT, -1, 0) lblLine1.Text = "Line Count: " & (linecount).ToString lblLine2.Text = "Char Count: " & TextBox1.Text.Length If linecount > 6 Then TextBox1.Focus() SendKeys.Send("{BKSP}") End If End Sub
When I use an UltraTextEditor control the code does not work.
I need to restrict the number the lines. Is there a way to do this?
John
John;
I'd like to use your code, with the .Controls[0] modification...what's the declaration for EM_GETLINECOUNT?
Do I need a Using System.xml or something ?
Thanks.
Harry Gross
Hi Harry,
In NetAdvantage 2010 Volume 2, we added support for GetLineCount and some other SendMessage calls on our editor controls. So you can now use them directly.
Anyway... I don't think I have a sample of the syntax for this. I recommend checking out Microsoft's documentation on calling API's from DotNet. Or just do a search on the web, there are a few sites out there that have already written the declarations of these API's for you.
Also note that the API you are looking for here is SendMessage. EM_GETLINECOUNT is the message you will send, not the API itself.
Hi,
Have you tried this outside of TextChanged?
I just tested it out using a button with AlwaysInEditMode set to both true and false and it's working fine for me either way. I didn't try it inside the TextChanged event, but perhaps you are running into some sort of timing issue with that event.
I tried to put the AutoSize function everywhere I could, inside, outside the text_changed event, and I cannot make it work except when typing inside.
I replaced the ultratexteditor by a standard winform RichTextBox and it works fine... I am using a scenario where controls are created a dynamic way. Perhaps some tricky situations are not well handled yet by the ultratexteditor ?
That's possible, but without being able to see this bug actually occurring, I'm not sure how that could be the case.
When the UltraTextEditor is in edit mode, getting the line count is actually just a simple matter of passing off the Windows API message to the embedded TextBox control within the UltraTextEditor. So if this is failing, it's the inbox TextBox control that is failing. If that's the case, then my best guess is that there is some sort of timing issue regarding when you are calling the method.
If you can post a sample demonstrating this not working, I would be happy to take a look at it.
Hello Mike, here is what I managed to reproduce so far. Just copy paste below in an empty class file.
Its a form with two buttons and a UltraTextBox.
When you type in the UltraTextBox using a couple of carriage returns, notice its height will adjust itself :
=> this works fine
Unfortunately, when you use the "Add Lines" button to add some lines, you will see that it is no longer the case.
=> here is the bug
When swiching the focus through all the control, I notice that the text in the UltraTextBox changes : all the RC disappears.
It sounds like the embedded TextBox is no longer in sync with the other one.
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WindowsFormsApplication4 { public class Form1 : Form { private Infragistics.Win.UltraWinEditors.UltraTextEditor ultraTextEditor1 = new Infragistics.Win.UltraWinEditors.UltraTextEditor(); private Infragistics.Win.Misc.UltraButton Clear = new Infragistics.Win.Misc.UltraButton(); private Infragistics.Win.Misc.UltraButton AddLine = new Infragistics.Win.Misc.UltraButton(); public Form1() { this.ultraTextEditor1.Location = new System.Drawing.Point(12, 13); this.ultraTextEditor1.Multiline = true; this.ultraTextEditor1.Name = "ultraTextEditor1"; this.ultraTextEditor1.Size = new System.Drawing.Size(277, 78); this.ultraTextEditor1.TextChanged += new System.EventHandler(this.ultraTextEditor1_TextChanged); this.Clear.Location = new System.Drawing.Point(295, 41); this.Clear.Name = "Clear"; this.Clear.Size = new System.Drawing.Size(134, 22); this.Clear.Text = "clear text"; this.Clear.Click += new System.EventHandler(this.Clear_Click); this.AddLine.Location = new System.Drawing.Point(295, 13); this.AddLine.Name = "Add Lines"; this.AddLine.Size = new System.Drawing.Size(134, 22); this.AddLine.Text = "Add lines"; this.AddLine.Click += new System.EventHandler(this.ultraButton1_Click); this.ClientSize = new System.Drawing.Size(438, 232); this.Controls.Add(this.Clear); this.Controls.Add(this.AddLine); this.Controls.Add(this.ultraTextEditor1); this.Name = "Form1"; this.Text = "Test form"; } private void Clear_Click(object sender, EventArgs e) { ultraTextEditor1.Clear(); } const int EM_GETLINECOUNT = 0xBA; public static void AdaptHeight(Control ut) { var rows = (int)SendMessage(ut.Handle, EM_GETLINECOUNT, IntPtr.Zero, IntPtr.Zero); ut.Height = rows * ut.Font.Height + 1 + ut.Margin.Vertical; } [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); private void ultraTextEditor1_TextChanged(object sender, EventArgs e) { AdaptHeight(ultraTextEditor1); } private void ultraButton1_Click(object sender, EventArgs e) { var txt = ultraTextEditor1.Text; ultraTextEditor1.Text = txt += "bla\nblabla\nblablabla"; // AdaptHeight(ultraTextEditor1); } } }
Okay, I am able to see the problem using the code you posted here. As I suspected, this is a timing issue. When the control is not in edit mode and therefore there is no inbox TextBox control, UltraTextEditor uses it's UIElements to determine the line count.
The problem here is that when you change the text and the TextChanged event fire, the display has not yet been updated. The control hasn't painted, yet, with the new text. So it's still using the old text and the old UIElements to measure.
You can get around this very easily by simply calling the Update method to force the control to redraw if needed right before you call SendMessage.
public static void AdaptHeight(Control ut) { ut.Update(); var rows = (int)SendMessage(ut.Handle, EM_GETLINECOUNT, IntPtr.Zero, IntPtr.Zero); ut.Height = rows * ut.Font.Height + 1 + ut.Margin.Vertical; }
Hello Peter,
After some research, the "LinesCount property for UltraTextEditor" has been determined to be a new product idea. I have sent your idea directly to our product management team.
Our product team chooses new ideas for development based on popular feedback from our customer base. Infragistics continues to monitor application development for all of our products, so as trends appear in requested features, we can plan accordingly.
We value your input, and our philosophy is to enhance our toolset based on customer feedback. If your idea is chosen for development, you will be notified at that time.
Your reference number for this product idea is PI12050061.
If you would like to follow up on your request at a later point, you may contact Developer Support management via email. Please include the reference number of your product idea in the subject and body of your email message. You can reach Developer Support management through the following email address: dsmanager@infragistics.com
Thank you for your request.
System.Windows.Forms.TextBox has a Lines count property for multiline feature,
http://msdn.microsoft.com/en-us/library/system.windows.forms.textboxbase.lines%28v=vs.80%29.aspx
To offer direct control replacement can't you provide the same property? Why a new property named GetLineCount?
ControlBreak said:Argh, your workaround is working fine in the sample, but it fails in my "real life project" (where controls are dynamically created :-/)
The only way I can think of that that might make a difference is if the control is not visible and so the Update method doesn't do anything. So you might need to set Visible to true. You might also want to check IsHandleCreated on the control. If there's no handle, then Update probably won't work, either. In such a case, you could hook into the control's HandleCreated event and then get the line count and size the control at that point.
Argh, your workaround is working fine in the sample, but it fails in my "real life project" (where controls are dynamically created :-/)
I will mark your answer as accepted anyway, since it's the explanation about what is happening. I will try to build another prototype as soon I have some time and post it here later.