Shi
Shi

Reputation: 3

Itemsstackpanel disables scrolling

I have an Itemsstackpanel inside a Listview Control. I want to fire the PointerWheelChanged event whenever the User is near the edge of a page. When i put the event on the itemsstackpanel is disables my ability to scroll by mouse wheel. If the event is on the Listview or Grid itself it only works as long as no Items are done loading in the Listview. Is this intended behaviour or am i missing some important information? I researched but found no lead to this problem or behaviour.

below is my XAML:

    <Grid Background="Gray">
    <ProgressRing x:Name="progress" IsActive="False" x:FieldModifier="public" Foreground="Black" Height="200" Width="200"/>
    <ListView x:Name="ListViewControl" x:FieldModifier="public" Margin="10,10,10,10" ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
              ScrollViewer.ZoomMode="Enabled" ScrollViewer.VerticalScrollBarVisibility="Visible" DataFetchSize="10" IncrementalLoadingTrigger="Edge" 
              IncrementalLoadingThreshold="2" ShowsScrollingPlaceholders="True" BorderThickness="1" IsItemClickEnabled="False" SelectionMode="None" PointerEntered="ListViewControl_PointerEntered">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsStackPanel CacheLength="0" Orientation="Vertical" Background="White" PointerWheelChanged="Grid_PointerWheelChanged"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>

    </ListView>


</Grid>

and the code behind(not done just trying to get it to work for now):

    private  void ItemsStackPanel_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
    {
        e.Handled = true;

       
        PointerPoint pointerPoint = e.GetCurrentPoint(ListViewControl);

        
        float scrolledDistance = pointerPoint.Properties.MouseWheelDelta;

   
        if (scrolledDistance >=120)
        {
            //Load Page above current Page at a certain mousewheel point

        }
        else if (scrolledDistance <= -120 )
        {
            //Load Page below current Page at certain mousewheel point
        }
        else
        {
            //do some other stuff
        }
    }

Upvotes: 0

Views: 115

Answers (1)

Anran Zhang
Anran Zhang

Reputation: 7727

The default ControlTemplate of ListView contains a ScrollViewer control. PointerWheelChanged is a relatively low-level event that will be intercepted by ScrollViewer.

If you want to monitor the change of the scrolling distance, PointerWheelChanged is not a recommended event. You can listen to the ScrollViewer.ViewChanged event and use ScrollViewer.VerticalOffset to determine the vertical scrolling distance.

We can create a custom ListView to achieve this:

CustomListView.cs

public class CustomListView:ListView
{
    private ScrollViewer _scrollViewer;

    public event EventHandler<ScrollViewerViewChangedEventArgs> ViewChanged;

    public CustomListView()
    {
        this.DefaultStyleKey = typeof(ListView);
    }

    protected override void OnApplyTemplate()
    {
        _scrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
        if (_scrollViewer != null)
        {
            _scrollViewer.ViewChanged += CustomViewChange;
        }
        base.OnApplyTemplate();
    }

    private void CustomViewChange(object sender, ScrollViewerViewChangedEventArgs e)
    {
        ViewChanged?.Invoke(sender, e);
    }
}

Usage

<controls:CustomListView x:Name="ListViewControl"
                         ViewChanged="ListViewControl_ViewChanged"
                         ...>
    <!--other content-->
</controls:CustomListView>
private void ListViewControl_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
    var scrollViewer = sender as ScrollViewer;
    double scrollHeight = scrollViewer.VerticalOffset;
    if (scrollHeight > 120)
    {
        //Do Something...
    }
    else
    {
        //Do something...
    }
}

Upvotes: 1

Related Questions