尝试做一些基于滚动的触发器,如何根据滚动位置(顶部,中间,底部,值)实现自定义routedevent触发器raise / fire
with top,当元素进入顶部滚动视图
底部,当元素进入底部滚动视图
中,进入中间滚动视图
值,达到特定的滚动位置
我的目的是为wpf
模仿一些基于滚动的触发动画答案 0 :(得分:0)
我看到了三个解决方案:
public class ScrollEventTrigger : System.Windows.Interactivity.EventTrigger
{
public ScrollUnit Unit { get; set; }
public double VerticalOffset { get; set; }
protected override string GetEventName()
{
return "ScrollChanged";
}
protected override void OnEvent(EventArgs eventArgs)
{
var args = (ScrollChangedEventArgs)eventArgs;
var scrollViewer = (ScrollViewer)args.Source;
var verticalOffsetAbs = VerticalOffset;
if (Unit == ScrollUnit.Relative)
{
verticalOffsetAbs = VerticalOffset*scrollViewer.ViewportWidth;
}
//you have to play more with this condition, because you may scroll directly from 0.4 to 0.6 and the 0.5 can be skipped.
if (args.VerticalOffset == verticalOffsetAbs)
{
base.OnEvent(eventArgs);
}
}
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent e) {
Player p = e.getPlayer();
if(plugin.spectating.contains(p)) {
if(e.getRightClicked() instanceof Player) {
Player target = (Player) e.getRightClicked();
if(plugin.alive.contains(target)) {
target.setPassenger(p);
}
}
}
}
答案 1 :(得分:0)
我看到了三个解决方案:
这种方法的优点是,您可以在控件样式中轻松使用它。 缺点是,当必须触发事件时,您无法配置准确的位置,并且必须进行硬编码。
<ScrollViewer x:Name="ScrollViewer1">
<ScrollViewer.Triggers>
<EventTrigger RoutedEvent="my:ScrollViewerExtension.ScrolledTop">
<BeginStoryboard Storyboard="{StaticResource ScrolledTopAnimations}" />
</EventTrigger>
<EventTrigger RoutedEvent="my:ScrollViewerExtension.ScrolledToMiddle">
<BeginStoryboard Storyboard="{StaticResource ScrolledToMiddleAnimations}" />
</EventTrigger>
</ScrollViewer.Triggers>
</ScrollViewer>
public static class ScrollViewerExtension
{
public static readonly RoutedEvent ScrolledTopEvent = EventManager.RegisterRoutedEvent("ScrolledTop", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ScrollViewerExtension));
public static void AddScrolledTopHandler(DependencyObject d, RoutedEventHandler handler)
{
((UIElement) d).AddHandler(ScrolledTopEvent, handler);
var scrollViewer = (ScrollViewer) d;
scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged; //to avoid multiple subscription
scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged;
}
public static void RemoveScrolledTopHandler(DependencyObject d, RoutedEventHandler handler)
{
((UIElement)d).RemoveHandler(ScrolledTopEvent, handler);
}
static void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.VerticalOffset == 0)
{
((UIElement)sender).RaiseEvent(new RoutedEventArgs(ScrolledTopEvent, sender));
}
//else if... trigger other events
//else if
}
}
答案 2 :(得分:0)
我看到了三个解决方案:
当然,我们不能忘记使用代码背后的最简单的解决方案。只需比较其他解决方案所需的代码数量:
void ScrollViewer1_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.VerticalOffset == 0)
{
((Storyboard)FindResource("ScrolledTopAnimations")).Begin();
}
//else if... trigger other animations
//else if
}