Limit the max number of chars per line in a textbox

前端 未结 5 1854
慢半拍i
慢半拍i 2021-01-25 23:24

Say I have the following:



        
相关标签:
5条回答
  • 2021-01-25 23:42

    Given that you're responding to keydown events I assume that you want to make sure that the string behind the TextBox adheres to the "60 chars per line" rule. If that's the case you should make an event that subscribes to the TextChanged event on the TextBox. There you can fix up the text and either truncate or break apart lines that are too long.

    (edit) To solve the display portion you can do as Kafuka suggested: just make the box wide enough to hold 60 characters, and use a monospaced font if you want to be sure. If you've made sure the string is correct this should fall into line easily.

    0 讨论(0)
  • 2021-01-25 23:43

    I know this is an extremely late answer, but so that people who find this can get a good answer, with protection against for instance Ctrl+C and stuff:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        foreach (string line in textBox1.Lines)
        {
            if (line.Length > 60)
            {
                textBox1.Undo();
            }
        }
    
        textBox1.ClearUndo();
    }
    

    Note that this does mean you cannot use Ctrl+Z in the textbox anymore but if that doesn't bother you this is a good option, because it works with any font.

    EDIT This doesn't work with wpf textboxes, only windows forms textboxes

    0 讨论(0)
  • 2021-01-25 23:43

    I have looked at several solutions today. They either don't work at all, or if they work, they don't work the way I think they should. Oddities with cursor position, or wrapping incorrectly. Here is my "solution", and I hope it helps someone in the future. It wraps, doesn't unwrap, and keeps any existing new lines. I set this example to 60 characters wide, and a bool isBusyUpdating outside of this example to keep it from firing again when the update is in progress.

            txtNotes.HorizontalContentAlignment = HorizontalAlignment.Left;
            txtNotes.VerticalContentAlignment = VerticalAlignment.Top;
            txtNotes.TextWrapping = TextWrapping.NoWrap;
            txtNotes.AcceptsReturn = true;
            txtNotes.TextChanged += delegate (object o, TextChangedEventArgs args)
            {
                //args.Handled = true;
                TextBox thisText = (TextBox)args.Source;
                 if (!isBusyUpdating)
                {
                    isBusyUpdating = true;
                    string updatedText = "";
                    bool blnUpdate = false;
                    int curPos = thisText.CaretIndex;
    
                    foreach (string thisLine in thisText.Text.Split('\n'))
                    {
    
                        if (thisLine.Length > 60)
                        {
                            blnUpdate = true;
                            updatedText = updatedText + 
                                thisLine.Substring(0, 60)
                                .Replace("\n", "") +
                                          "\n" + thisLine.Substring(60);
                            curPos++;
                        }
                        else
                        {
                            updatedText = updatedText + thisLine + "\n";
                        }
                    }
    
                    if (blnUpdate)
                    {
                        thisText.Text = updatedText;
                        thisText.CaretIndex = curPos-1;
                    }
                    isBusyUpdating = false;
    
                }
    
            };
    
    0 讨论(0)
  • 2021-01-25 23:50

    Choose a mono spaced font. And calculate the width of your textbox that has 60 chars.

    0 讨论(0)
  • 2021-01-25 23:57

    I do not really think that you can do this while wrapping because wrapping would change the current line to fit the TextBox. Even while using Notepad, you can never view the Status Bar while enabling the Word Wrap as it will be difficult to get the current line index and its length while wrapping.

    I've managed to set the maximum characters per line while the TextWrapping property is set to NoWrap. You'll first need to get the length of the current line index. Then, in case it's 59 or more, handle the input.

    Example

    <TextBox Name="textBox1"
             TextWrapping="NoWrap" 
             AcceptsReturn="True" 
             AcceptsTab="True" 
             MaxLines="3000"
             KeyDown="textBox1_KeyDown"/>
    
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        //Initialize a new int of name CurrentLine to get the current line the user is on
        int CurrentLine = textBox1.GetLineIndexFromCharacterIndex(textBox1.Text.Length);
    
        //Continue if the length of the current line is more or equal to 59
        if (textBox1.GetLineLength(CurrentLine) >= 59) 
        {
            //Don't insert the character
            e.Handled = true; 
        }
    }
    

    Thanks,
    I hope you find this helpful :)

    0 讨论(0)
提交回复
热议问题