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?
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>
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With