繁体   English   中英

防止TextBox中的文本水平滚动

[英]Prevent text inside TextBox from scrolling horizontally

我有一个WPF应用程序,其中有许多TextBox元素。 用户填写这些内容,然后应用程序将其打印出来。 TextBoxes的问题在于,如果您继续输入,则将其填满到最后,文本将开始水平滚动以为更多的字母腾出空间,并且您不再看到输入的前几个字母。

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

我查看了TextBox属性,却没有看到可以直接实现我想要的功能的任何东西。 第一个想法是将包装设置为Wrap。 然后订阅PreviewTextInput事件,如果行数将超过1,则在不添加新键入文本的情况下处理该事件。 显然,您仍然可以通过粘贴文本来解决此问题,但是更大的问题是它仅适用于单行TextBoxes,我也需要它与多行TextBoxes一起使用。

是否有我所缺少的更好的方法? 将计算文本宽度,然后确保它小于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

您正在寻找MaxLength属性。 您必须试验一下数字,因为您需要记住,在可以容纳一个W的空间中可以容纳很多i。通常,当我调整TextBoxes的大小时,我会根据W进行大小调整并设置最大长度,因为那最广泛的角色。

编辑:刚看到您希望它也与多行文本框一起使用...在这种情况下,只需将其设置为自动换行,它就不会水平滚动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM