防止TextBox内的文本水平滚动

时间:2015-09-30 20:18:49

标签: c# wpf textbox

我有一个WPF应用程序,它有一些TextBox元素。用户将其填满,然后应用程序将其打印出来。 TextBoxes的问题在于,如果你继续输入一个,一旦你把它填写到最后,文本开始水平滚动为更多的字母腾出空间,你不再看到输入的第一对几个字母。

决定解决方案是阻止用户输入更多适合TextBox的文本。最好的方法是什么?

我查看了TextBox属性,并没有看到任何可以直接执行我想要的操作。第一个想法是将包装设置为Wrap。然后订阅PreviewTextInput事件,如果行数超过1,则处理事件而不添加新输入的文本。显然你仍然可以通过粘贴文本来解决它,但更大的问题是它只适用于单行TextBox,我需要它也可以使用多行TextBox。

我缺少更好的方法吗?计算文本宽度,然后确保它小于TextBox宽度/高度(如何?)是一个更好的选择?或许是另一种解决方案?

2 个答案:

答案 0 :(得分:1)

这是我的最终解决方案,也适用于多行TextBox。粘贴文本时它甚至可以工作。唯一奇怪的是,当文本溢出时,我删除尾随字符,如果您在文本框的中间键入文本,这可能看起来很奇怪。我尝试通过删除CaretIndex中的字符来解决这个问题,但它过于介入了。但除此之外它完成了我需要做的事情。为了提高性能,您可以缓存GetLineHeight函数的结果,这样您只需要每个TextBox调用一次(编辑 - 我也为此添加了代码)。

<TextBox Height="23" Width="120" TextWrapping="Wrap"  TextChanged="TextBoxTextChanged" AcceptsReturn="True"/>

private void TextBoxTextChanged(object sender, TextChangedEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (textBox == null)
        return;

    double textLineHeight = GetCachedTextLineHeight(textBox);
    int maxTextBoxLines = (int)(textBox.ViewportHeight / textLineHeight);

    while (textBox.LineCount > maxTextBoxLines) //if typed in text goes out of bounds
    {
        if (textBox.Text.Length > 0)
            textBox.Text = textBox.Text.Remove(textBox.Text.Length - 1, 1); //remove last character

        if (textBox.Text.Length > 0)
            textBox.CaretIndex = textBox.Text.Length;
    }
}

private double GetTextLineHeight(TextBox textBox)
{
    FormattedText formattedText = new FormattedText(
        "a",
        CultureInfo.CurrentUICulture,
        FlowDirection.LeftToRight,
        new Typeface(textBox.FontFamily, textBox.FontStyle, textBox.FontWeight, textBox.FontStretch),
        textBox.FontSize,
        Brushes.Black);

    return formattedText.Height;
}

#region Caching

Dictionary<TextBox, double> _cachedLineHeights = new Dictionary<TextBox, double>();

private double GetCachedTextLineHeight(TextBox textBox)
{
    if (!_cachedLineHeights.ContainsKey(textBox))
    {
        double lineHeight = GetTextLineHeight(textBox);
        _cachedLineHeights.Add(textBox, lineHeight);
    }

    return _cachedLineHeights[textBox];
}

#endregion

答案 1 :(得分:0)

您正在寻找MaxLength酒店。你必须要对这个数字进行试验,因为你需要记住你可以在你可以容纳一个W的空间中安装很多我。通常当我调整TextBoxes时,我会调整大小并设置最大值基于W的长度,因为那是最广泛的角色。

编辑:刚看到你想要它也可以使用多行文本框......在这种情况下,只需将其设置为包装,它就不会水平滚动。