如何根据宽度值获取字符串的一部分?

3

我有一个自定义的圆形文本框,不想将文字写到圆角部分,因此想知道从字符串开头到指定宽度有多少个字符。我知道使用TextRenderer.MeasureText测量字符串,但它只给出字符串的宽度,无法反向运作。我该怎么办?

有时候我可以做到这一点,但可能需要花费很长时间。

    string resultText = string.Empty;

    for (int i = 0; i < Text.Length; i++)
    {
       resultString = Text.Substring(0, i);
       if (TextRenderer.MeasureText(resultText, Font).Width <= textWidth)
          break;
    }

1
这是什么类型的应用程序?请使用适当的标记。 - sujith karivelil
这是一个Windows窗体应用程序。 - Ali Tor
除非您使用固定宽度字体,否则所有字符的宽度都将不同,因此您需要做类似于这样的事情。 - TaW
2
你的方法没问题...你可能可以通过LINQ在语法上减少for循环,但我会说你的方法没问题...当然,你也可以通过某种递归的“二分查找”方式,从中间开始切割并根据宽度评估结果向左或向右移动...这样稍微复杂一些,但对于长字符串可能会更快。但如果字符串不是那么长,你所做的可能已经足够好了。 - Ian
@lan,我认为你的方法比使用暴力风格更好。通过递归地将其分成两部分,它可以更快。如果我能做到的话,我会添加的。 - Ali Tor
我现在有一个更好的解决方案,并已经写成了答案。 - Ali Tor
1个回答

0

我找到了一种更好的解决方案,不需要循环。在这种方法中,我们计算当前宽度和目标宽度之间的比率。如果将此比率乘以字符串的当前长度,我们就可以得到一个良好的子字符串点。

 string GetSubStringToWidth(string orgText, int width, Font font)
    {
        int orgWidth = TextRenderer.MeasureText(orgText, font).Width;

        float ratio = (float)width / orgWidth;

        int length = (int)(orgText.Length * ratio);

        if (length >= orgText.Length) return orgText;
        else if (length <= 0) return "";
        else
        {
            //May be more sensitive if we go right or left one unit because of letter unequalities
            int mid = Math.Abs(width - TextRenderer.MeasureText(orgText.Substring(0, length), font).Width);
            int right = Math.Abs(width - TextRenderer.MeasureText(orgText.Substring(0, length + 1), font).Width);
            int left = Math.Abs(width - TextRenderer.MeasureText(orgText.Substring(0, length - 1), font).Width);

            int i = Math.Min(Math.Min(mid, right), left);
            int point = 0;

            if (i == mid)
                point = length;
            else if (i == right)
                point = length + 1;
            else
                point = length - 1;

            return orgText.Substring(0, point);
        }
    }

我怀疑这在各种内容上都不会很好用。并且,我怀疑你对时间的担忧没有任何实际理由。“过早的优化是万恶之源”。当然,截断文本通常会导致截断的文本... - TaW
我只在我的代码中进行了测试。它已经将文本设置在文本框的中间,这正是我想要的。我不确定它是否适用于所有内容,但越好越好。 - Ali Tor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接