Как предотвратить прокрутку окна редактирования WPF, чтобы закончить на программном SelectAll? - PullRequest
2 голосов
/ 06 июля 2010

У меня есть TextBox, который выполняет SelectAll (), когда он получает фокус. Работает отлично. Проблема в том, что если содержимое не помещается в поле, то SelectAll приводит к прокрутке содержимого до конца. Я хочу, чтобы вместо этого он прокручивался вперед - это поле используется с числовыми полями.

Мой вопрос: возможно ли выбрать SelectAll (), но избежать прокрутки?

Обходной путь, который я имею сейчас, состоит в том, чтобы поставить ScrollToHome в очередь. Мне это не очень нравится, потому что это иногда вызывает треск, когда текст отображается в одной позиции, затем в другой.

    public new void SelectAll()
    {
        base.SelectAll();

        // changing selection does something with a queued scroll request, so have to queue ours in the back. this still may cause a flash
        // if a render slips through. would like to find a better way to do this.
        Dispatcher.BeginInvoke(DispatcherPriority.Background, ScrollToHome);
    }

Обратите внимание, что ScrollToHome должен быть поставлен в очередь следующим образом или он «перезаписывается» из-за какого-либо другого события в очереди. Я покопался в источнике, и он довольно сложный, мне было трудно понять, где именно он делает запрос на прокрутку.

Итак, что я ищу, так это одно из следующих:

  1. Как выбрать All () без прокрутки или прокрутки вперед.
  2. Как принудительно обновить отображение, чтобы я не получил всплывающее окно.

Ответы [ 2 ]

3 голосов
/ 07 июля 2010

Оберните ваши SelectAll() и ScrollToHome() вызовы с BeginChange() и EndChange(). Это спасет его от перекраски:

public new void SelectAll()
{
    BeginChange();
    SelectAll();
    ScrollToHome();
    EndChange();
}

Другой вариант - потерять фокус с TextBox, а затем сделать выбор.

0 голосов
/ 05 сентября 2012

У меня была точно такая же проблема (текстовое поле, которое выбирает все, когда оно получает фокус, и я хочу, чтобы оно прокручивалось до начала, а не до конца), но в серебряном свете.Там нет BeginChange / EndChange, поэтому я в основном придумал и ответ Скотта Биласа.

Это означает, что я вижу перекрашенный, что разочаровывает, но это лучшее, что я могу придумать на данный момент.Чтобы сделать его еще более хакерским, просто BeginInvoke недостаточно, так как автопрокрутка до дна ставится в очередь и иногда происходит после действия BeginInvoke, поэтому мне приходится вводить искусственную задержку (порождение в новом потоке и сон в течение 10 мс перед BeginInvoke) чтобы получить его более надежным.Итак, я закончил с этим:

var scrollViewer = VisualTreeWalker.FindVisualChildren<ScrollViewer>(TextBox)
    .FirstOrDefault();

new Thread(delegate()
{
    Thread.Sleep(10);
    scrollViewer.Dispatcher.BeginInvoke(() =>
    {
        scrollViewer.ScrollToLeft();
        scrollViewer.ScrollToTop();
    });
}).Start();

Я играл с наблюдателем свойства зависимостей, чтобы наблюдать HorizontalOffset ScrollViewer в текстовом поле, а затем выполнил BeginInvoke, когда HorizontalOffset стал ненулевым, но этопросто потребовалось слишком много особых случаев ... что если в текстовом поле недостаточно текста, чтобы вызвать автопрокрутку, чтобы горизонтальное смещение оставалось равным 0?Тогда правая пользовательская правка, которая должна вызывать прокрутку, будет прокручиваться обратно вверх / влево.Она просто превратилась в большую кроличью нору, поэтому мне пришлось довольствоваться этим ужасным хаком.

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