I suppose there's a limit for the lines alowed in a TextBox with the MultiLine option set to true.
I have a program that every several minutes, checks an email account, but for control purposes i put a TextBox that indicates what's been doing.
My curiosity is, does anyone know how much lines are allowed ? And does throw an exception when reached that line ?
EDIT Sorry forgot to mention is in WinForms
EDIT 2 Perhaps, someone knows of a way to eliminate older lines, will grated appreciated
There's no limit on the number of lines that a text box can display.
There is, however, a limit on the number of characters that the control can hold. See this question for further details on this topic.
If you set the TextBox.MaxLength property to zero, the amount of text is limited only by available memory.
Another solution:
<TextBox x:Name="txtAddress"
MaxLines="6"
TextWrapping="Wrap" AcceptsReturn="True"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden"
TextChanged="txtAddress_TextChanged"
PreviewTextInput="txtAddress_PreviewTextInput"
PreviewKeyDown="txtAddress_PreviewTextInput"/>
//...
private void txtAddress_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox txtBx = sender as TextBox;
if (txtBx.LineCount > txtBx.MaxLines)
txtAddress.Text = this._textBeforInput;
}
private string _textBeforInput = string.Empty;
private void txtAddress_PreviewTextInput(object sender, EventArgs e)
{
this._textBeforInput = txtAddress.Text;
}
There is no such limitation on Multiline TextBox both in WinForms and ASP.NET. (I have no idea of WPF :) )
I know this question is really old and has already been answered, but for those searching for an HTML/ASP.NET solution I have created a short jsFiddle http://jsfiddle.net/Z3rdZ/2/
HTML
<textarea id="limited-lines" maxlines="4"></textarea>
jQuery
$('#limited-lines').keydown(function(event){
if ( event.which == 13 ) {
var numberOfLines = $(this).val().split('\n').length;
if(numberOfLines >= $(this).attr('maxlines')){
event.preventDefault();
}
}
});
Related
OK, so I am trying to apply the accounting number format for all textboxes on my Form.
Now, I did some research here and found this post that will help me to set the format.
And then I found another post to apply the format for all textbox controls on the form without adding the format code individually to all controls.
Well, the thing is that the code on the format uses the control name, which will bind it to a single textbox control. I tried the control name (TextoBox) instead, and it also failed.
There is another issue to consider, that even if I manage to get past the above problem, the code from format is an event, named after the control name, so I do not think it will work if I apply it to a class or method and call for it.
While I already do have the solution to what I want, I would like to know if there is a faster way to apply it, which will not add so much lines to my code. Trying to learn how to keep things easier to read, doing less with more. Any advise?
Thanks for reading.
It sounds like you have all the pieces, just need help putting it together. For the ControlName, you can cast the sender object to the control and access its Name property.
void SetProperty(Control ctr)
{
foreach (Control control in ctr.Controls)
{
if (control is TextBox)
{
control.Leave += control_Leave;
}
else
{
if (control.HasChildren)
{
SetProperty(control);
}
}
}
}
void control_Leave(object sender, EventArgs e)
{
var textBox = sender as TextBox;
Double value;
if (Double.TryParse(textBox.Text, out value))
textBox.Text = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:C2}", value);
else
textBox.Text = String.Empty;
}
Usage:
SetProperty(this);
Also, from my comment on the OP: If accounting is truly important, I would suggest using the Decimal type instead of Double. Double will be faster, but Decimal is more precise. Figure out which trade off makes sense and make a decision based on that.
Edit per comments:
myTextBox.Leave -= control_Leave
If you know the name of the control, the above will work. You will need to do this after you use SetProperty(this). If you want to handle this inside the SetProperty() method, do a check on control.Name == "myTextBox".
You can subscribe multiple controls event(that use the same args) to the same event handler :
public YourFormConstructor()
{
foreach(var textbox in form.Controls.OfType<TextBox>())
textbox.Leave += FormatCurrencyText;
}
private void FormatCurrencyText(object sender, EventArgs e)
{
var textbox = sender as TextBox;
Double value;
if (Double.TryParse(textbox.Text, out value))
textbox.Text = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:C2}", value);
else
textbox.Text = String.Empty;
}
I have custom ComboBox, where DropDownStyle = ComboBoxStyle.DropDown;.DropDown style is set because I want to set the Text property of the ComboBox to something outside the list of values. Everything works good, except that ComboBox is highlighting the text when it's left and when I click on the combobox editing is avaible. How can I cope with this?
To illustrate:
First Picture is where everything looks good, second is the highlight situation, third editing is on.
Try un-selecting the text after the DropDown closes:
void comboBox1_DropDownClosed(object sender, EventArgs e) {
this.BeginInvoke(new Action(() => { comboBox1.Select(0, 0); }));
}
If you are referring to disabling the highlighting and editing, then you might want to consider setting the DropdownStyle property to DropdownList.
yourComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
Tricky problem to solve. It seems to be from the Resize event. There are a lot of solutions that do something similar to this, but none that I've seen worked for me until I tried this. (This is a solution that does not require inheritance from ComboBox; inheriting is probably a much more straight forward solution, but requires you to always use your inherited class and never the actual ComboBox class.)
comboBox.Resize += (s, e) => {
if (!comboBox.IsHandleCreated)
return; // avoid possible exception
comboBox.BeginInvoke(new Action(() => comboBox.SelectionLength = 0));
};
Set the selection length to zero to get rid of the highlight, but when? Other examples do it in other places, but the problem seems to be specifically caused by Resize, so doing it after Resize fixes it consistently, at least for me. (Can still see it flicker when you resize the window though, but it always ends up ok.)
BeginInvoke ensures that it happens sufficiently after Resize to work, and the check for IsHandleCreated prevents it from being called before the handle is created, in which case BeginInvoke would throw an exception.
This slightly more complex version includes some checks to prevent a focused control from losing highlight, since it actually should have it. It also doesn't fire if the parent doesn't exist yet, or if the parent does not have an active control yet, both signs that things are too early.
comboBox.Resize += (s, e) => {
if (!comboBox.IsHandleCreated)
return;
comboBox.BeginInvoke(new Action(() => {
var parent = comboBox.FindForm();
if (parent == null)
return;
if (parent.ActiveControl == null)
return;
if (parent.ActiveControl == comboBox)
return;
comboBox.SelectionLength = 0;
}));
};
I tried to make a version that would 'preserve' the selection length rather than always set it to zero, but I couldn't get it to synchronize properly. Many Resize events can fire before the BeginInvoke delegates start to fire, so the preserved value will always be overwritten by the broken one. I tried saving them all in a Queue or Stack, but in both cases, I was unable to reverse the ordering (not really sure why, since that makes no sense).
To solve the same I have tried almost EVERYTHING:
setting the DropdownStyle property to DropdownList
this.BeginInvoke(new Action(() => { comboBox1.Select(0, 0); }));
combobox1.SelectionLength = 0;
changing comboBox.TabIndex
Not tried SendKeys.Send("{ESC}"); because it is not a reliable solution
Nothing helped.
The only stable and working solution was to move a focus on another Label control:
label.Focus();
You could also hide that label.
I know this post is old but recently I have the same problem with combobox.
Situation : I have an editable combobox which propose complete words when user write some letters.
But when I want to type a letter, combobox auto highlight the text and the next letter auto replace the previous.
Solution : I use a textbox to avoid any highlight like that:
<ComboBox IsTextSearchEnabled="False" IsEditable="True" x:Name="CMB_ClientName"/>
<TextBox Text="{Binding ElementName=CMB_ClientName, Path=Text}" TextChanged="ComboBoxChange" x:Name="TXT_ClientName"/>
And I generate the textbox TextChanged event :
private void ComboBoxChange(object sender, TextChangedEventArgs e)
{
//Clear ComboBox items
CMB_ClientName.Items.Clear();
//Auto Open DropDownList
CMB_ClientName.IsDropDownOpen = true;
//Get data from database (use entity framework 6.x)
dbEntity.Client.Load();
//Attribute Data to variable
var clients = dbEntity.Client.Local;
foreach (Client client in clients)
{
//If data begin with the texbox text, the data is add to the combobox items list.
if (client.Nom.ToLower().StartsWith(TXT_NomClient.Text.ToLower()))
{
CMB_ClientName.Items.Add(client.Nom);
}
}
}
I know this solution isn't realy beautifull, but it is for me the easiest solution to avoid highlight text and all the solutions in this post don't work for me.
I hope this solution will be helpfull, thanks for reading.
Math.
Ps: My apologies, my English is not very good. I hope you will understand me correctly.
Nothing worked for me ( I want the form to load with no highlighting in any combobox) until I set the combobox property TabStop to false. This meant that one of my buttons took the tab highlight which I didn't like so I set them all to false for start up and adjusted them programatically as needed.
I know this is an old thread, but my solution is similar to that of the others, but relies on the Form.ResizeEnd event. In its event handler, I iterate through the ComboBoxes and set ComboBox.SelectionLength to 0.
private void Form_ResizeEnd(object sender, EventArgs e)
{
foreach(ComboBox comboBox in parentControl.Controls.OfType<ComboBox>
{
comboBox.SelectionLength = 0;
}
}
This is what worked for me:
Set DrawMode to OwnerDrawFixed
Set cbxSubsystems.DrawItem event to the function below
private void cbxSubsystems_DrawItem(object sender, DrawItemEventArgs e)
{
Color BgClr;
Color TxClr;
if( (e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit )
{
// Do not highlight main display
BgClr = cbxSubsystems.BackColor;
TxClr = cbxSubsystems.ForeColor;
}
else
{
BgClr = e.BackColor;
TxClr = e.ForeColor;
}
e.Graphics.FillRectangle(new SolidBrush(BgClr), e.Bounds);
TextRenderer.DrawText(e.Graphics, cbxSubsystems.Items[e.Index].ToString(), e.Font, e.Bounds,
TxClr, BgClr, TextFormatFlags.Left | TextFormatFlags.VerticalCenter );
}
I'm building a Xaml based app with a C# backend.
I have data that needs to be entered by the user in a specific format (example: AAAA-BBBBBB-CCCC-DD etc). I currently have one text box that takes the whole thing, but for user experience I would prefer to break the example text into four boxes
one for AAAA
one for BBBBBB
one for CCCC
one for DD etc
So what I expect from the user would be abundantly clear. That part is easy enough with string concatenation
But I would like the four boxes to behave like a single box in a largely transparent manner.
Once the user enters 4 characters into textbox 1, the focus would shift to textbox 2 and they could continue typing. Additionally, if possible, I would like the focus shift to select all text already in the box, so they can easily overwrite without having to go to their mouse or doing a ctrl+a.
I've searched for how to change focus between texboxes, but could not get examples to work.
You can listen to TextChanged event of each TextBox, then check if text length is equal maximum length. If it is equal (or even greater) than maximum, move focus to next TextBox and select all text there. Refactor the logic to a method so you can simply call the same method in event handler function of each TextBox, hence can avoid writing similar codes repeatedly. Something like this will do :
private void textboxAAAA_TextChanged(object sender, TextChangedEventArgs e)
{
HandleTextChanged(textboxAAAA, textboxBBBBBB, 4);
}
private void textboxBBBBBB_TextChanged(object sender, TextChangedEventArgs e)
{
HandleTextChanged(textboxBBBBBB, textboxCCCC, 6);
}
private void textboxCCCC_TextChanged(object sender, TextChangedEventArgs e)
{
HandleTextChanged(textboxCCCC, textboxDD, 4);
}
private void HandleTextChanged(TextBox currentTextBox, TextBox nextTextBox, int maxLength)
{
var textLength = currentTextBox.Text.Length;
if (textLength >= maxLength)
{
nextTextBox.Focus(FocusState.Keyboard);
nextTextBox.SelectAll();
}
}
//in XAML
<StackPanel Orientation="Horizontal">
<TextBox x:Name="textboxAAAA" Width="60" TextChanged="textboxAAAA_TextChanged"/>
<TextBlock Text="-"/>
<TextBox x:Name="textboxBBBBBB" Width="60" TextChanged="textboxBBBBBB_TextChanged"/>
<TextBlock Text="-"/>
<TextBox x:Name="textboxCCCC" Width="60" TextChanged="textboxCCCC_TextChanged"/>
<TextBlock Text="-"/>
<TextBox x:Name="textboxDD" Width="60"/>
</StackPanel>
Note, that you don't consider case when user copy-paste serial number. What the program should do if user copy 7 letters text, and paste it to the first text box?
Other solution:
1.- You configure sequencial TabIndex properties in your four TextBoxes.
2.- You configure maxLength propoerties en your TextBoxes.
3.- You configure the next method in TextChanged event in your TextBoxex.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var tb = (TextBox)sender;
if (tb.Text.Length == tb.MaxLength)
{
var nextTB = this.PrincipalGrid.Children.OfType<TextBox>().Where(t => t.TabIndex == (tb.TabIndex + 1)).FirstOrDefault();
if (nextTB != default(TextBox))
nextTB.Focus();
}
}
Why not to use one TextBox? Listen for text changes and include a dash(-) in text every time when it need. Do not allow user to type dashes (ignore them). Some small logic should be done for clipboard pasting and for the whole product key/text validation. Later you can split the Text via String.Split( new Char("-")) and you will get an array of codes (if you need it in this way).
I'm using Bindings to populate a Listbox, with TextBlocks, etc.
The question is :
How do I make sure that the text bound to the the Text property of a TextBlock is of specific length, or that it is displayed trimmed at some specific character length (e.g. "some very very long t..."), so that the text doesn't "overflow" the phone screen or its container?
Since Mango SDK, there is a property call TextTrimming.
So this xaml
<TextBlock Text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" TextTrimming="WordEllipsis" Width="200" />
will produce somehting like "aaaaaaa....."
Tricky one! I forced myself to think that if the characters exceeds, say some 10 then i am going to append dots to it. So i added this textchanged event to the textbox and then made the code as follows:
private void TestTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string temp = TestTextBox.Text;
if (temp.Length > 10)
{
char[] charArray=temp.ToCharArray();
temp = new string(charArray, 0, 10);
temp += "...";
}
TestTextBox.Text = temp;
}
Really really odd problem, in short, I'm doing a foreach over every word in a textblock, if that word starts with for example "#" I want to make a username hyperlink out of it. However in about 70% of the cases it replaces the text fine, but it just doesn't become a hyperlink.
Partial code:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var kaas = Tweet.Split(' ');
foreach (string a in kaas)
{
if (a.StartsWith("#"))
{
Hyperlink uname = new Hyperlink();
uname.NavigateUri = new Uri("http://twitter.com/" + "xarinatan");
uname.RequestNavigate += new RequestNavigateEventHandler(Hyperlink_RequestNavigateEvent);
uname.Inlines.Add("ASDAS");
TweetBlock.Inlines.Add(uname);
//TweetBlock.Inlines.Add(Username(a));
TweetBlock.Inlines.Add(" ");
}
}
}
Above code turns all instances that start with "#" into "ASDAS" but fails most of the time to properly convert it to a hyperlink, HOWEVER it DOES convert it SOMETIMES.
It's completely beyond me how it only works sometimes, instead of all the time or not at all.
All suggestions are welcome!
edit: To clarify, it -always- replaces the text with 'ASDAS', but in 70% of the cases it doesn't become a hyperlink.
My friend found the answer. Somehow inlines being added as string causes sporadic behavior, they have to be added as a 'Run'.
Fix can be found here: https://github.com/zahndy/o3o/commit/68b50f8c0ea106bcc709d3f69658b28da9c8a9d4#diff-3
Thanks all for the suggestions!