• UWP忽略短时间内重复触发的事件


    原链接:UWP忽略短时间内重复触发的事件 - 超威蓝火

    做移动端开发的可能都会遇到这种需求,当用户点击一个按钮之后,由于没有异步,或者设备性能很差等等原因,程序卡住了。但是用户不知道是咋回事啊,就开始狂点按钮,结果请求很多次资源,或者构造了很多重复视图。安卓上有很多介绍如何忽略重复点击的情况,uwp里我好像还没找到,那接下来就说一说我的方法吧。
    首先是官方最常用的,从Windows诞生之初用到现在的,点击按钮之后把他Disable掉,等完成了在Enable。其实这算是最好的选择了,但是总归是麻烦了一些,尤其是在MVVM的时候,每个Button都要单独绑定一个IsEnabled,所以接下来就仿照安卓上的通用处理方法试一下。
    首先创建一个类,我们就叫他EventWaiter吧,里面维护一个LastTime,一个IsEnabled,事件可以判断这个IsEnabled来知道,上一次点击和这一次点击的间隔是不是过短,从而决定是否要执行。

    public class EventWaiter
    {
        private DateTime _lastTime;
    
        public EventWaiter(double seconds)
        {
            Interval = TimeSpan.FromSeconds(seconds);
        }
    
        public EventWaiter(TimeSpan interval)
        {
            Interval = interval;
        }
    
        public EventWaiter()
        {
            Interval = TimeSpan.FromSeconds(0.1d);
        }
    
        //间隔
        public TimeSpan Interval { get; set; }
    
        public bool IsEnabled
        {
            get
            {
                if(DateTime.Now - _lastTime > Interval)
                {
                    _lastTime = DateTime.Now;
                    return true;
                }
                return false;
            }
        }
    
        public void Reset()
        {
            _lastTime = DateTime.Now;
        }
    }
    

    大概用法是这样的:

    
    var waiter = new EventWaiter();
    
    var button = new Button();
    button.Click += OnClick;
    
    private void OnClick(object sender,RoutedEventArgs e)
    {
        if(waiter.IsEnabled)
        {
            //do something 
        }
    }
    
    

    接下来就是第三种需求了。对于安卓iOS来说,很少有SizeChanged,但是UWP不一样啊,UWP能窗口运行啊,所以在一些要响应SizeChanged,在窗口大小改变的时候做一些很重操作的时候,拖拽窗口就会变得非常卡,所以我现在想忽略拖动窗口的中间过程,只让他响应最后状态。而上面的EventWaiter,是一段时间内只响应第一次事件的触发,和我们的需求是完全反着的。
    这时候就要请救星:DispatcherTimer出来了(感谢小竹)。
    大致思路呢,按时间顺序叙述,是当原事件触发时,让Timer开始运行;第二次触发事件时判断Timer是否运行,如果正在运行呢,就停掉重新启动,相当于重置了计时器;等Timer第一次跑完,执行Tick的时候停掉Timer,并且激活内部的事件去做真正的操作。
    我们再弄个新的类,起个名字叫EventDelayer(原谅我起名困难),里面需要维护一个DispatcherTimer,还要一个事件Arrived负责在最后被触发,和一个Delay()方法,负责进入触发判断。

    public class EventDelayer
    {
        private DispatcherTimer _timer;
    
        public EventDelayer(double seconds) : this(TimeSpan.FromSeconds(seconds))
        {
        }
    
        public EventDelayer(TimeSpan interval)
        {
            _timer = new DispatcherTimer();
            _timer.Tick += _timer_Tick;
            Interval = interval;
        }
    
        public EventDelayer() : this(0.1)
        {
        }
    
        public TimeSpan Interval
        {
            get => _timer.Interval;
            set => _timer.Interval = value;
        }
    
        public bool ResetWhenDelayed { get; set; }
    
        public void Delay()
        {
            if (!_timer.IsEnabled)
            {
                _timer.Start();
            }
            else
            {
                if (ResetWhenDelayed)
                {
                    _timer.Stop();
                    _timer.Start();
                }
            }
        }
    
    
        private void _timer_Tick(object sender, object e)
        {
            if (_timer.IsEnabled)
            {
                _timer.Stop();
            }
            OnArrived();
        }
    
        public event EventHandler Arrived;
        protected void OnArrived()
        {
            Arrived?.Invoke(this, EventArgs.Empty);
        }
    
    }
    
    

    用法大概是这个样子:

    var delayer = new EventDelayer();
    
    delayer.Arrived += OnArrived;
    
    this.SizeChanged += OnSizeChanged;
    
    private void OnSizeChanged(object sender, SizeChangedEventArgs e)
    {
        delayer.Delay();
    }
    
    private void OnArrived(object sender,EventArgs args)
    {
        //do something
    }
    
    
    

    炒鸡完美。github:https://github.com/cnbluefire/ReaderView/tree/master/ReaderView/Common/Helpers

  • 相关阅读:
    刚听完CSDN总裁蒋涛先生的学术报告
    WinForm下屏幕截图程序的实现
    .NET4.5 Async 与 Async Targeting Pack区别
    WP8中的Tiles
    WP8中调用APP的方式
    安装Win8后必做的优化
    如何将项目从WP7升级到WP8
    ActiveWriter集成到VS.NET的NHibernate(ActiveRecord)对象可视化设计工具
    概述CSLA.NET 3.6 (Overview of CSLA .NET 3.6 for Windows and Silverlight)
    SQL Server BI Step by Step 1 准备
  • 原文地址:https://www.cnblogs.com/blue-fire/p/10025010.html
Copyright © 2020-2023  润新知