Obtaining caret position in TextBox

一笑奈何 提交于 2019-12-22 08:37:17

问题


How to get caret position (x, y) in the visible client zone in TextBox control? I need to add an auto complete feature to the text box.

I've found solution for WPF, but it can't be applied in Silverlight.


回答1:


public class AutoCompleteTextBox : TextBox
{
    public Point GetPositionFromCharacterIndex(int index)
    {
        if (TextWrapping == TextWrapping.Wrap) throw new NotSupportedException();

        var text = Text.Substring(0, index);

        int lastNewLineIndex = text.LastIndexOf('\r');

        var leftText = lastNewLineIndex != -1 ? text.Substring(lastNewLineIndex + 1) : text;

        var block = new TextBlock
                        {
                            FontFamily = FontFamily,
                            FontSize = FontSize,
                            FontStretch = FontStretch,
                            FontStyle = FontStyle,
                            FontWeight = FontWeight
                        };

        block.Text = text;
        double y = block.ActualHeight;

        block.Text = leftText;
        double x = block.ActualWidth;

        var scrollViewer = GetTemplateChild("ContentElement") as ScrollViewer;

        var point = scrollViewer != null
                        ? new Point(x - scrollViewer.HorizontalOffset, y - scrollViewer.VerticalOffset)
                        : new Point(x, y);
        point.X += BorderThickness.Left + Padding.Left;
        point.Y += BorderThickness.Top + Padding.Top;

        return point;
    }
}



回答2:


In addition to altso's answer, I'd like to mention that you actually need to call .Measure() and .Arrange() methods on the block for .ActualHeight and .ActualWidth to work, for example, like this (parameters may vary depending on your use case):

 block.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
 block.Arrange(new Rect(0, 0, block.DesiredSize.Width, block.DesiredSize.Height));
 double y = block.ActualHeight;

This is required in WPF, and advised in Silverlight (including SL5). Otherwise you'll end up having 0 in ActualHeight in WPF and weird numbers in Silverlight (in my case, these were coordinates of a bounding box around all text).


As a separate solution, you could use FormattedText class to do the same trick.



来源:https://stackoverflow.com/questions/1921220/obtaining-caret-position-in-textbox

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!