wpf 限制文本框中每行的最大字符数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13733679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Limit the max number of chars per line in a textbox
提问by Vaccano
Say I have the following:
说我有以下几点:
<TextBox TextWrapping="Wrap"
AcceptsReturn="True"
AcceptsTab="True"
MaxLines="3000"/>
Is there a way I can limit the max number of chars per line to 60?
有没有办法可以将每行的最大字符数限制为 60?
I have seen ways to do it via keydown events, but that does not seem to be foolproof (ie what about pasting in a long block of text).
我已经看到了通过 keydown 事件来做到这一点的方法,但这似乎并不是万无一失的(即粘贴一长段文本怎么样)。
回答by
Choose a mono spaced font. And calculate the width of your textbox that has 60 chars.
选择单间距字体。并计算具有 60 个字符的文本框的宽度。
回答by RandomEngy
Given that you're responding to keydown events I assume that you want to make sure that the string behind the TextBoxadheres to the "60 chars per line" rule. If that's the case you should make an event that subscribes to the TextChangedevent on the TextBox. There you can fix up the text and either truncate or break apart lines that are too long.
鉴于您正在响应 keydown 事件,我假设您想确保后面的字符串TextBox符合“每行 60 个字符”规则。如果是这样的话,你应该做的是订阅了事件TextChanged的事件TextBox。在那里您可以修复文本并截断或拆分太长的行。
(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.
(编辑)要解决显示部分,您可以按照 Kafuka 的建议进行操作:只需将框宽度设置为足以容纳 60 个字符,如果您想确定,请使用等宽字体。如果您确定字符串是正确的,这应该很容易对齐。
回答by Picrofo Software
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 Barwhile enabling the Word Wrapas it will be difficult to get the current line index and its length while wrapping.
我真的不认为您可以在换行时执行此操作,因为换行会更改当前行以适合TextBox. 即使在使用Notepad 时,您也永远无法在启用自动换行时查看状态栏,因为在换行时很难获得当前行索引及其长度。
I've managed to set the maximum characters per line while the TextWrappingproperty 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.
当TextWrapping属性设置为NoWrap. 您首先需要获取当前行索引的长度。然后,如果它是 59 或更多,处理输入。
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 :)
谢谢,
我希望你觉得这有帮助:)
回答by Dennis van Gils
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:
我知道这是一个非常晚的答案,但是这样的人可以得到一个很好的答案,例如 Ctrl+C 和其他东西:
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.
请注意,这确实意味着您不能再在文本框中使用 Ctrl+Z,但如果这不会打扰您,这是一个不错的选择,因为它适用于任何字体。
EDITThis doesn't work with wpf textboxes, only windows forms textboxes
编辑这不适用于 wpf 文本框,只有 Windows 窗体文本框
回答by Billy Willoughby
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.
我今天看了几个解决方案。它们要么根本不工作,要么即使工作,也不会按照我认为的方式工作。光标位置异常,或包装不正确。这是我的“解决方案”,我希望它在未来对某人有所帮助。它包装,不展开,并保留任何现有的新行。我将此示例设置为 60 个字符宽,并在此示例之外设置了一个 bool 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;
}
};

