UI.WPF.Modern icon indicating copy to clipboard operation
UI.WPF.Modern copied to clipboard

Unable to make TextBox to auto scroll to bottom when it's being updated.

Open kevwkev opened this issue 1 year ago • 6 comments

The ScrollToEnd() function appears ineffective with TextBox, tested in both code-behind and MVVM utilizing a behavior extension of the TextBox control.

===code-hehind===

  1. Use x:name. Subscribed to TextChanged event.
  2. Call textbox.ScrollToEnd() in TextChanged event.

===behavior extension for MVVM====

public class ScrollToEndBehavior
{
    public static readonly DependencyProperty OnTextChangedProperty =
                DependencyProperty.RegisterAttached(
                "OnTextChanged",
                typeof(bool),
                typeof(ScrollToEndBehavior),
                new UIPropertyMetadata(false, OnTextChanged)
                );

    public static bool GetOnTextChanged(DependencyObject dependencyObject)
    {
        return (bool)dependencyObject.GetValue(OnTextChangedProperty);
    }

    public static void SetOnTextChanged(DependencyObject dependencyObject, bool value)
    {
        dependencyObject.SetValue(OnTextChangedProperty, value);
    }

    private static void OnTextChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var textBox = dependencyObject as TextBox;
        var newValue = (bool)e.NewValue;

        if (textBox == null || (bool)e.OldValue == newValue)
        {
            return;
        }

        TextChangedEventHandler handler = (object sender, TextChangedEventArgs args) =>
            ((TextBox)sender).ScrollToEnd();

        if (newValue)
        {
            textBox.TextChanged += handler;
        }
        else
        {
            textBox.TextChanged -= handler;
        }
    }
} 

kevwkev avatar Jan 26 '24 04:01 kevwkev

Hi! Thank you for reporting this. It seems that this is the problem made by the control ScollViewerEx.cs. I'll check that later cuz I'm in the weeds right now. 😕

NotYoojun avatar Jan 26 '24 07:01 NotYoojun

Help needed! I can't solve this after a few attempts.

NotYoojun avatar Jan 29 '24 13:01 NotYoojun

https://github.com/iNKORE-Public/UI.WPF.Modern/blob/89322a8d2d41683d42e9f623ee6129ac1c46ab58/source/iNKORE.UI.WPF.Modern/Controls/ScrollViewerEx.cs#L106-L115

~~这段注释掉就正常了,但是不知道有无副作用~~ ~~有点难评但是管用~~

~~个人感觉是ScrollInfoAdapter.SetVerticalOffset(double offset)执行动效的时候寄了~~

Zaitonn avatar Feb 04 '24 05:02 Zaitonn

https://github.com/iNKORE-Public/UI.WPF.Modern/blob/89322a8d2d41683d42e9f623ee6129ac1c46ab58/source/iNKORE.UI.WPF.Modern/Themes/Styles/TextBox.xaml#L148-L163

(把ScrollViewerEx改成ScrollViewer也能正常滚到末尾

Zaitonn avatar Feb 04 '24 06:02 Zaitonn

把 ScrollViewerEx 改成 ScrollViewer 的方案是不可取的。ScrollViewerEx 存在的意义就是修复和优化 WPF 自带的垃圾滚动逻辑。我们解决这个问题只能从 ScrollViewer 本身下手。

NotYoojun avatar Feb 13 '24 01:02 NotYoojun

I don't know how far your testing did go, I just realized both functions ScrollToHome and ScrollToEnd do work a single time after the application is started. Then I found out they work again after the contrary function is called, meaning a not working ScrollToEnd function does work again after ScrollToHome is called once.

In conclusion there is at least a workaround for now, just call ScrollToHome everytime before you call ScrollToEnd. It works in my test project, within a slower program or an a slower machine, adding texts fast, I would imaging this approach to be problemtic though.

Byolock avatar May 07 '24 16:05 Byolock