Хватит прокручивать RichTextBlock при запуске манипуляции - PullRequest
0 голосов
/ 23 января 2020

У меня есть чат, содержащий RichTextBlock

<ScrollViewer Name="ChatScroll"
                              Margin="3"
                              ManipulationMode="All">
                    <i:Interaction.Behaviors>
                        <helpers:ScrollHelper />
                    </i:Interaction.Behaviors>
                    <RichTextBlock>
                        <Paragraph>
                            <InlineUIContainer>
                                <ItemsControl ItemsSource="{Binding SelectedMedia.ChatMessages}"
                                      Margin="0">
                                    //SOME ELSE CODE
                                </ItemsControl>
                            </InlineUIContainer>
                        </Paragraph>
                    </RichTextBlock>
                </ScrollViewer>

Так что мне нужно прокрутить внизу при получении нового сообщения, НО, если я хочу просмотреть историю чата, мне не нужно прокручивать вниз.

Моя идея состоит в том, чтобы подписаться на событие ManipulationDelta и отменить прокрутку вниз

public class ScrollHelper : Behavior<ScrollViewer>
{
    private double height = 0.0d;
    private ScrollViewer scrollViewer = null;
    private bool IsBusy = false;

    protected override void OnAttached()
    {
        base.OnAttached();
        //IsBusy = false;
        this.scrollViewer = this.AssociatedObject;
        this.scrollViewer.LayoutUpdated += ScrollViewer_LayoutUpdated;
        this.scrollViewer.ManipulationDelta += ScrollViewer_ManipulationDelta;
    }


    private void ScrollViewer_ManipulationDelta(object sender, Windows.UI.Xaml.Input.ManipulationDeltaRoutedEventArgs e)
    {
        var verticalOffset = scrollViewer.VerticalOffset;
        var maxVerticalOffset = scrollViewer.ScrollableHeight; //sv.ExtentHeight - sv.ViewportHeight;

        if (maxVerticalOffset < 0 ||
            verticalOffset == maxVerticalOffset)
        {
            IsBusy = false;
        }
        else if (e.Delta.Translation.Y < 0 || e.Delta.Translation.Y > 0)
        {
            IsBusy = true;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        if (this.scrollViewer != null)
        {
            this.scrollViewer.LayoutUpdated -= ScrollViewer_LayoutUpdated;
        }
    }
    private void ScrollViewer_LayoutUpdated(object sender, object e)
    {
        if (!IsBusy)
        {
            if (Math.Abs(this.scrollViewer.ExtentHeight - height) > 1)
            {
                scrollViewer.ChangeView(0, scrollViewer.ExtentHeight, 1);
                this.height = this.scrollViewer.ExtentHeight;
            }
        }
    }
}

Но если я прокручиваю колесико мыши, то событие не работает? Есть идея как подписаться на событие колеса прокрутки? Или другие идеи, как не отправить прокрутку вниз при просмотре истории

1 Ответ

1 голос
/ 24 января 2020

Есть ли идея, как подписаться на событие колеса прокрутки?

Событие колеса мыши будет обрабатываться внутри скроллера, поэтому мы не могли подписаться на это событие напрямую, в общем, мы могли бы подписаться на ViewChanging событие, содержащее FinalView и NextView, и мы можем сравнить VerticalOffset из FinalView и NextView, чтобы судить прокрутку вниз или вверх.

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