Управление позицией прокрутки TextBox из ViewModel? - PullRequest
1 голос
/ 29 февраля 2012

Есть ли решение, включающее WPF TextBox / Block, который автоматически прокручивается до конца с помощью привязки?Очевидно, что это можно сделать в коде позади, вызвав элемент управления напрямую, но как сделать это с Binding и MVVM?

в коде, который работает (но я бы хотел этого избежать и использоватьВМ делать все)

  public void _readerService_BytesArrived(string s)
  {
     Action dispatcherAction = () =>
     {
        txtBoxOutPut.AppendText(s);
        txtBoxOutPut.ScrollToEnd();
     };
     Dispatcher.Invoke(dispatcherAction);
  }

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012

Я думаю, что вы пытаетесь прокрутить до конца, когда значение Text изменяется внутри TextBox / Block.Поскольку это операция, связанная с просмотром, она должна оставаться такой.Просто поместите событие TextChanged в элемент управления и прокрутите до конца, когда свойство Text изменится.


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

1 голос
/ 29 февраля 2012

Поведение System.Windows.Interactivity может помочь вам.Я использую их для прокрутки различных элементов управления, и это не в виртуальной машине, но это также не в представлении и следует MVVM.

Ниже приведен пример Scrollviewer, который может быть полезным

    public class FrameworkElementScrollviewerScrollingBehavior : Behavior<FrameworkElement>
{
    private FrameworkElement _AssociatedElement;

    private ScrollViewer _listboxScrollViewer = null;

    #region OnAttached
    protected override void OnAttached()
    {
        base.OnAttached();
        _AssociatedElement = AssociatedObject;
        _AssociatedElement.Loaded += OnControlLoaded;
        _AssociatedElement.Unloaded += new RoutedEventHandler(_AssociatedElement_Unloaded);

        //TODO: register/subscrive for event/message from the VM that tells you the scrollviewer to do something
    }

    //TODO: handle the event using the _AssociatedElement as the control you are acting on

    void _AssociatedElement_Unloaded(object sender, RoutedEventArgs e)
    {
        Cleanup();
    }
    #endregion

    #region OnDetaching
    protected override void OnDetaching()
    {
        Cleanup();
        base.OnDetaching();
    }
    #endregion

    private bool _isCleanedUp;
    private void Cleanup()
    {
        if (!_isCleanedUp)
        {
            _AssociatedElement.Loaded -= OnControlLoaded;
            _AssociatedElement.Unloaded -= _AssociatedElement_Unloaded;
        }
    }


    #region OnControlLoaded
    private void OnControlLoaded(object sender, RoutedEventArgs args)
    {
        FrameworkElement element = sender as FrameworkElement;
        if (element != null)
        {
            _listboxScrollViewer = GetDescendantByType(sender as Visual, typeof(ScrollViewer)) as ScrollViewer;

            if (_listboxScrollViewer.ComputedVerticalScrollBarVisibility == Visibility.Visible)
                //do something when content is scrollable
        }
    }
    #endregion

    #region GetDescendantByType
    /// <summary>
    /// Gets the descendent of type
    /// </summary>
    /// <param name="element">The element.</param>
    /// <param name="type">The type.</param>
    /// <returns></returns>
    public static Visual GetDescendantByType(Visual element, Type type)
    {
        if (element == null) return null;

        if (element.GetType() == type) return element;
        Visual foundElement = null;
        if (element is FrameworkElement)
            (element as FrameworkElement).ApplyTemplate();
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
        {
            Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
            foundElement = GetDescendantByType(visual, type);
            if (foundElement != null)
                break;
        }
        return foundElement;
    }
    #endregion
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...