c# - 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
}
}
解决方案
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...
}
}
推荐阅读
- substrate - 余额保持为零
- flutter - 按下后退按钮并重新打开应用程序 Flutter 卡在启动画面
- python - 使用 JSON 对象展开 Pandas DataFrame 列
- python - 我无法从正则表达式匹配中创建列表
- sql - Postgres (SQL) 查找未保留的总天数
- python - 尽管安装成功,但术语“pip”在 Windows 10 上未被识别为 cmdlet 的名称
- c# - 以编程方式编辑实时excel文档c#
- windows-installer - ISDEV:致命错误 -7108:%s 太大而无法存储在 .cab 中(最大 2 GB)
- typescript - 太复杂的打字稿问题。动态对象引用
- android - ExoPlayer 2.11.1 默认带宽表();已弃用