Есть ли стандартный способ отменить события в Silverlight? - PullRequest
2 голосов
/ 30 июня 2011

Я ищу что-то похожее на jQuery throttle / debounce , но для Silverlight.Мы хотели бы отменить событие выбора, измененного в нашем приложении Silverlight - поэтому, если пользователь быстро меняет выбор быстро, мы реагируем на изменение только тогда, когда пользователь перестал его менять.Я не думаю, что это будет сложно написать, и я не ищу пример кода - просто интересно, встроен ли он или доступен в какой-то общей библиотеке.Если нет, я сверну свою собственную, используя DispatcherTimer.

Спасибо,Ричард

Ответы [ 2 ]

2 голосов
/ 30 июня 2011

Регулирование событий не встроено в Silverlight.Прежде чем вы приступите к реализации своей собственной версии, я бы взглянул на реактивные расширения для silverlight .Одна из функций называется именно так: Throttle, и она делает то, что подразумевает ее название.Единственная проблема, с которой я сталкиваюсь с реактивными расширениями, заключается в том, что dll довольно большие, поэтому, если вы хотите, чтобы ваш xap-файл был маленьким, вы можете захотеть использовать собственную реализацию.

0 голосов
/ 03 июня 2014

Reactive Extensions очень мощный, но мне пришлось свернуть свой собственный для проекта.Вот оно:

using System.Timers;
public static class EventExtensions {
    static Dictionary<EventHandler, Timer> _debounceTimers;

    public static EventHandler Debounce(TimeSpan interval, Action<object, EventArgs> action) {
        object lastSender = null;
        EventArgs lastArgs = null;

        var timer = new Timer();
        if (_debounceTimers == null)
            _debounceTimers = new Dictionary<EventHandler, Timer>();

        timer.Interval = interval.TotalMilliseconds;
        timer.Elapsed += (sender, args) => {
            timer.Enabled = false;
            timer.Stop();

            action(lastSender, lastArgs);
        };

        EventHandler handler = (sender, args) => {
            lastSender = sender;
            lastArgs = args;

            timer.Stop();
            timer.Start();
            timer.Enabled = true;
        };

        _debounceTimers.Add(handler, timer);

        return handler;
    }

    public static void DisposeDebouncers(this EventHandler handler) {
        handler.ThrowIfNull("handler");

        if (_debounceTimers.ContainsKey(handler)) {
            var timer = _debounceTimers[handler];
            if (timer != null) {
                timer.Stop();
                timer.Enabled = false;
                timer.Dispose();
            }
        }
    }
}

Test

using Xunit;
public class EventExtensionsTest {

    event EventHandler FrequentEvent;

    [Fact]
    void DebounceTest() {
        var counter = 0;
        var span = TimeSpan.FromSeconds(1);
        var handler = EventExtensions.Debounce(span, (sender, e) => counter++);
        FrequentEvent += handler;

        FrequentEvent(this, null);
        FrequentEvent(this, null);
        FrequentEvent(this, null);

        Thread.Sleep(2000);
        Assert.Equal(1, counter);

        FrequentEvent(this, null);
        FrequentEvent(this, null);
        FrequentEvent(this, null);
        FrequentEvent(this, null);
        FrequentEvent(this, null);

        Thread.Sleep(2000);
        Assert.Equal(2, counter);

        FrequentEvent.DisposeDebouncers();
        FrequentEvent -= handler;
    }
}

object.ThrowIfNull() - это метод расширения, который выдает ArgumentNullException, если объект имеет значение null.Я уверен, что есть непокрытые крайние случаи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...