【问题标题】:ISupportIncrementalLoading from bottom to topISupportIncrementalLoading 从下到上
【发布时间】:2013-01-26 07:18:21
【问题描述】:

我在 WinRT 中实现了 ISupportIncrementalLoading 以在 ListView 中进行增量加载,效果很好。 问题是新项目被添加到列表底部,要查看更多项目,我需要往下看。我需要的是相反的。我希望看到更多项目,我需要向上滚动。 该列表基本上是一个日志文件,最新的日期必须显示在列表的底部,如果我想查看较旧的记录,我需要使用向上滚动。

有办法吗?

【问题讨论】:

  • 不太清楚我是否理解,您是说当记录增量加载时您希望列表自动滚动到底部?
  • ISupportIncrementalLoading 增量加载添加到 ListView 底部的记录,然后,如果我想查看更多记录,我需要使用 ListView 控件的向下滚动。我需要的是加载的记录添加在 ListView 的顶部,而不是底部。所以,我想加载更多记录,我需要使用 ListView 的向上滚动。它必须像 OutLook 一样工作,当我打开我的应用程序时,我想显示最近的电子邮件,最近的在 ListView 的底部。如果我想查看较旧的电子邮件,我需要使用向上滚动控件。
  • 这完全有道理,达比尔。所有的消息应用程序都是这样,最新消息在底部。打开任何短信应用程序。还有另一种方法可以做到这一点,但是 ListView 在列表顶部弹出一个新项目时会出现问题。 stackoverflow.com/questions/30292690/…

标签: c# xaml windows-8


【解决方案1】:

我知道,问题很旧,但我遇到了同样的问题,但没有找到好的解决方案。

所以我会把我的解决方案发布给其他有同样问题的人。

我的第一个解决方案是我自己的 IncrementalLoadCollection,它具有用于滚动和加载数据的自定义行为。 它工作正常,但对我来说不够好。

所以我尝试了另一个强大的 XAML 技巧,它运行良好,除了一个小的鼠标滚轮行为。它现在颠倒了:)。

解决方案非常简单且功能强大。只需将 ListView 的 ScrollViewer 旋转 180° 并将其翻转以使滚动条再次位于右侧。然后对 Items 执行相同的操作,以便它们再次正确。

就是这样。增量加载由 ListView 处理,触摸事件和滚动条正常工作,只是鼠标滚轮行为现在反转了。

我的代码

<ListView Grid.Row="1" x:Name="ChatListView" ItemsSource="{TemplateBinding ItemsSource}" 
                              SelectionMode="None"
                              IsItemClickEnabled="False"
                              IsZoomedInView="False"
                            ShowsScrollingPlaceholders="False"
                            VerticalContentAlignment="Top" 
                              VerticalAlignment="Stretch" 
                              Margin="10,5">
                        <ListView.ItemContainerStyle>
                            <Style TargetType="ListViewItem">
                                <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="ListViewItem">
                                            <ContentPresenter/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </ListView.ItemContainerStyle>
                        <ListView.ItemContainerTransitions>
                            <TransitionCollection/>
                        </ListView.ItemContainerTransitions>
                        <ListView.Template>
                            <ControlTemplate>
                                <Border BorderThickness="{TemplateBinding BorderThickness}"
                                        Padding="{TemplateBinding Padding}"
                                        BorderBrush="{TemplateBinding BorderBrush}"
                                        Background="{TemplateBinding Background}">
                                    <ScrollViewer ZoomMode="Disabled" x:Name="ScrollViewer" RenderTransformOrigin="0.5,0.5">
                                        <ScrollViewer.RenderTransform>
                                            <CompositeTransform Rotation="180" ScaleX="-1"/>
                                        </ScrollViewer.RenderTransform>
                                        <ItemsPresenter x:Name="ItemsPresenter"/>
                                    </ScrollViewer>
                                </Border>
                            </ControlTemplate>
                        </ListView.Template>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <controls:ChatMessageControl Message="{Binding Message}"
                                                             ChatFrom="{Binding Name}"
                                                             IsMy="{Binding IsMy}"
                                                             ShortTime="{Binding CreatedTime}"
                                                             RenderTransformOrigin="0.5,0.5">

                                    <controls:ChatMessageControl.RenderTransform>
                                        <CompositeTransform Rotation="180" ScaleX="-1"/>
                                    </controls:ChatMessageControl.RenderTransform>
                                </controls:ChatMessageControl>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

【讨论】:

  • 感谢您的救命稻草!我尝试通过检查滚动偏移和使用 走另一条路,但最后我想出了一个有问题的解决方案,大约 90% 的时间都有效。我正在制作一个 WP 应用程序,所以这个解决方案很好 b/c 没有鼠标!
  • 您是否尝试覆盖 OnMouseWheelChanged 以反转值?
  • 是的,我试过了。很久以前,但我认为问题在于,ScrollViewer 在内部处理 MouseWheel 事件,而您没有任何机会操纵它。另一个想法是隐藏滚动条并在外部创建第二个滚动条/滚动查看器并同步反转位置。这应该可以,但我还没有尝试过。
  • 这对我也有用,但鼠标滚轮对我来说是个大问题。有没有人为此找到合适的解决方案?我无法进行同步。
  • 谢谢!我被这个问题困扰了很长时间
【解决方案2】:

参考 Demetrius Axenowski 的回答,这是我反转鼠标滚轮输入的方法。

注意我将其用于仅限桌面的应用程序

1)在ListView的ScrollViewer中找到第一个Grid,并hook PointerWheelChanged事件。

        this._ScrollViewer = this.GetChildren<ScrollViewer>().FirstOrDefault();
        if (this._ScrollViewer == null)
        {
            throw new InvalidOperationException("ScrollViewer not found.");
        }

        this._ScrollViewerInsetBorder = this.GetChildren<Border>().FirstOrDefault();

        this._BorderInsetGrid = this.GetChildren<Grid>().FirstOrDefault();
        this._BorderInsetGrid.AddHandler(ScrollViewer.PointerWheelChangedEvent, new PointerEventHandler(this.SW_Handler_OnPointerWheelChanged), true);

2) 覆盖鼠标滚轮行为。

    double desiredVerticalOffset = 0;
    private void SW_Handler_OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
    {
        PointerPoint mousePosition = e.GetCurrentPoint(sender as UIElement);
        var delta = mousePosition.Properties.MouseWheelDelta;

        // calculate desiredOffset
        desiredVerticalOffset = desiredVerticalOffset + delta;

        // limit desiredOffset.
        desiredVerticalOffset = desiredVerticalOffset < 0 ? 0 : desiredVerticalOffset;
        desiredVerticalOffset = desiredVerticalOffset > _ScrollViewer.ScrollableHeight ? _ScrollViewer.ScrollableHeight : desiredVerticalOffset;

        if (delta < 0 || delta > 0)
        {
            _ScrollViewer.ChangeView(null, desiredVerticalOffset, null, false);
            e.Handled = true;
        }
    }

【讨论】:

    猜你喜欢
    • 2012-10-05
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多