Получение позиции каретки в TextBox - PullRequest
4 голосов
/ 17 декабря 2009

Как получить позицию каретки (x, y) в видимой клиентской зоне в элементе управления TextBox? Мне нужно добавить функцию автозаполнения в текстовое поле.

Я нашел решение для WPF , но его нельзя применить в Silverlight.

Ответы [ 2 ]

5 голосов
/ 17 декабря 2009
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 голосов
/ 30 марта 2015

В дополнение к ответу altso , я хотел бы отметить, что вам действительно нужно вызвать .Measure() и .Arrange() методы для блока, чтобы .ActualHeight и .ActualWidth работали Например, вот так (параметры могут отличаться в зависимости от вашего варианта использования):

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

Это требуется в WPF и рекомендуется в Silverlight (включая SL5). В противном случае вы получите 0 в ActualHeight в WPF и странные числа в Silverlight (в моем случае это были координаты ограничивающей рамки вокруг всего текста).


В качестве отдельного решения вы можете использовать класс FormattedText для того же трюка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...