【问题标题】:Limit the max number of chars per line in a textbox限制文本框中每行的最大字符数
【发布时间】:2012-12-05 22:31:01
【问题描述】:

假设我有以下内容:

<TextBox TextWrapping="Wrap" 
         AcceptsReturn="True" 
         AcceptsTab="True" 
         MaxLines="3000"/>

有没有办法可以将每行的最大字符数限制为 60?

我已经看到了通过 keydown 事件来做到这一点的方法,但这似乎并不是万无一失的(即粘贴到长文本块中怎么样)。

【问题讨论】:

  • 你试过设置宽度吗?
  • 您是希望将显示限制为每行 60 个字符,还是要强制它包含的实际字符串每行仅 60 个字符?

标签: c# .net wpf


【解决方案1】:

选择单间距字体。并计算包含 60 个字符的文本框的宽度。

【讨论】:

    【解决方案2】:

    鉴于您正在响应 keydown 事件,我假设您要确保 TextBox 后面的字符串符合“每行 60 个字符”规则。如果是这种情况,您应该在TextBox 上创建一个订阅TextChanged 事件的事件。在那里您可以修复文本并截断或拆分太长的行。

    (编辑)要解决显示部分,您可以按照 Kafuka 的建议进行操作:只需使框宽到足以容纳 60 个字符,如果您想确定的话,请使用等宽字体。如果您确定字符串是正确的,这应该很容易符合要求。

    【讨论】:

      【解决方案3】:

      我知道这是一个非常晚的答案,但是这样发现这个问题的人可以得到一个很好的答案,并防止例如 Ctrl+C 和其他东西:

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

      请注意,这确实意味着您不能再在文本框中使用 Ctrl+Z,但如果这不打扰您,这是一个不错的选择,因为它适用于任何字体。

      编辑这不适用于 wpf 文本框,仅适用于 windows 形式的文本框

      【讨论】:

      • 这似乎不起作用 - WPF 文本框 (msdn.microsoft.com/en-us/library/…) 没有“ClearUndo”方法。如果您多次撤消,这只会产生运行时错误。
      • 你说得对,这仅适用于 Windows 窗体文本框,已编辑
      【解决方案4】:

      我真的不认为您可以在换行时执行此操作,因为换行会更改当前行以适应 TextBox。即使在使用 记事本 时,您也永远无法在启用 自动换行 的同时查看 状态栏,因为很难获取当前行索引和包装时的长度。

      TextWrapping 属性设置为NoWrap 时,我设法设置了每行的最大字符数。您首先需要获取当前行索引的长度。然后,如果是 59 或更多,则处理输入。

      示例

      <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; 
          }
      }
      

      谢谢,
      希望对您有所帮助:)

      【讨论】:

        【解决方案5】:

        我今天查看了几种解决方案。他们要么根本不工作,要么如果他们工作,他们就没有按照我认为应该的方式工作。光标位置异常或换行不正确。这是我的“解决方案”,我希望它对未来的人有所帮助。它包装,不展开,并保留任何现有的新行。我将此示例设置为 60 个字符宽,并在此示例之外设置一个布尔值 isBusyUpdating 以防止它在更新进行时再次触发。

                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;
        
                    }
        
                };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-01
          相关资源
          最近更新 更多