首页 > 解决方案 > Itemsstackpanel 禁用滚动

问题描述

我在 Listview 控件中有一个 Itemsstackpanel。每当用户靠近页面边缘时,我想触发 PointerWheelChanged 事件。当我将事件放在 itemsstackpanel 上时,我无法通过鼠标滚轮滚动。如果事件在 Listview 或 Grid 本身上,则它仅在 Listview 中未加载任何项目时才起作用。 这是预期的行为还是我错过了一些重要信息? 我进行了研究,但没有发现导致此问题或行为的原因。

下面是我的 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>

和后面的代码(现在还没有完成,只是想让它工作):

    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
        }
    }

标签: c#xamluwp

解决方案


ListView默认ControlTemplate包含一个ScrollViewer控件。PointerWheelChanged是一个相对较低级别的事件,会被ScrollViewer.

如果要监听滚动距离的变化,PointerWheelChanged不推荐使用事件。您可以监听ScrollViewer.ViewChanged事件并使用ScrollViewer.VerticalOffset来确定垂直滚动距离。

我们可以创建一个自定义 ListView 来实现这一点:

自定义列表视图.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);
    }
}

用法

<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...
    }
}

推荐阅读