Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ISupportIncrementalLoading from bottom to top

Tags:

c#

windows-8

xaml

I have implemented ISupportIncrementalLoading in WinRT for incremental loading in a ListView, it works great. The problem is that the new items are added to bottom of list, to see more items, I need to go down. What I need is the opposite. I would like that to see more items, I would need to go scroll up. The list is basically a log file, the newest date must be displayed at bottom of the list, and if I want to see older records, I would need to use the scroll up.

Is there a way to do it?

like image 809
Dabiel Kabuto Avatar asked Jan 26 '13 07:01

Dabiel Kabuto


2 Answers

I know, the Question is old, but I had the same problem and didn't find a good solution.

So I will post my solution for other, who have the same problem.

My first solution was my own IncrementalLoadCollection with custom behaviors for scrolling and loading the data. It work OK, but not well enougth for me.

So I tried another powerfull XAML trick and it works perfectly, except one little mouse wheel behavior. It's reversed now :).

Solution is very simple and powerfull. Just rotate the ScrollViewer of the ListView with 180° and flipp it to have the scrollbar on the right again. Then do the same for the Items so they are correct again.

That's it. Incremental loading is handled by ListView, touch events and scrollbar works correct, just the mouse wheel behavior is reversed now.

My code

<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>
like image 82
Demetrius Axenowski Avatar answered Oct 21 '22 14:10

Demetrius Axenowski


Reffering to Demetrius Axenowski answer, this is my approach to reverse the mousewheel input.

NOTE i'm using this for a desktop-only App

1) Find the first Grid inside the ScrollViewer of the ListView and hook the PointerWheelChanged event.

        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) Override Mousewheel behavior.

    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;
        }
    }
like image 30
Jens Marchewka Avatar answered Oct 21 '22 15:10

Jens Marchewka