所以我在C#(而不是WPF)中构建自定义控件,我基本上想用鼠标实现文本突出显示。
如何在字符串中有效地找到给定Point
处的字符(例如,单击鼠标的位置)?我绘制了字符串的布局矩形,我可以计算每个字符的字符串长度,直到找到最接近鼠标点击的字符串...但必须有更好的方法。有什么建议吗?
答案 0 :(得分:3)
如果我必须这样做,我会向后看
我将文本作为控件中的string
成员输入,因此我始终知道控件中实际输入的内容(如Text
中的TextBox
属性)。
然后我会使用TextRenderer.MeasureText()
方法(http://msdn.microsoft.com/en-us/library/7sy6awsb.aspx),我会一直重复测量字符串的长度,直到我通过X坐标控件中的鼠标,然后我知道选择了多少个字符。
例如,假设用户在控件中写入了文本Hello
并且X坐标位于l
和o
之间,可能值为20
然后我会在以下字符串上反复调用MeasureText()
:
H
:宽度为5像素。He
:宽度为10像素。Hel
:宽度为14像素。Hell
:宽度为17像素。Hello
:宽度为22像素。然后我知道鼠标在l
和o
之间被击中,因此我会突出显示文字Hell
。
抱歉这个令人反感的例子=)
<强>更新强>
您可以通过以二进制搜索树的方式计算长度来优化这一点
就像你在电话簿中查找一个名字一样,你不是逐页看,而是在你走的时候分成两半,越来越近,直到它们肯定在这两页之间。
类似地,特别是对于控件的长字符串值,计算整个字符串的宽度,然后计算其长度的一半,并在那里分割。我认为那时候会是O(n log n)
当然,如果文本具有固定宽度=)
O(1)
答案 1 :(得分:2)
根据BeemerGuy的建议,你可以做的另一件事是预先计算一系列补偿。随着字符串的更改(用户类型或属性在代码中设置),您可以重新计算偏移数组。这样可以在点击鼠标时为您节省对MeasureFont的调用,并且可以使查找角色变得微不足道。您基本上迭代数组,直到找到最近的字符。由于偏移量是按值隐式排序的,因此您甚至可以使用二进制搜索来使其更有效。