WPF - удаление элемента управления с DispatcherTimer, похоже, не проходит - PullRequest
6 голосов
/ 05 февраля 2011

Я видел вопрос, заданный в StackOverflow о том, как правильно удалять элементы управления в WPF.Как правило, есть некоторые комментарии о том, что вы не можете утилизировать их вручную (или не можете), и если у вас нет ссылки на них, они будут в конечном итоге очищены GC.Я совершенно случайно заметил, что один из моих элементов управления, который, как мне показалось, был удален, застрял и все еще выполняет работу, даже если я удалил его из родительского элемента.

Я воссоздал пример как можно меньше строк.Элемент управления имеет DispatcherTimer.Вот код WPF для элемента управления, который я хочу удалить.

public partial class MyControl : UserControl
{
    private DispatcherTimer timer;
    public MyControl()
    {
        InitializeComponent();
        timer = new DispatcherTimer();
        timer.Tick += TimerOnTick;
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Start();
    }

    private void TimerOnTick(object sender, EventArgs args)
    {
        //this continues to get written out even after this control is removed.
        System.Diagnostics.Debug.WriteLine("Tick From MyControl.");
    }

}

Вот код для окна, которое добавляет и удаляет мой элемент управления.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void AddClicked(object sender, RoutedEventArgs e)
    {
        anyControlHolder.Children.Add(new MyControl());
    }

    private void RemoveClicked(object sender, RoutedEventArgs e)
    {
        anyControlHolder.Children.Clear();
    }
}

Проблема Iу меня, когда я запускаю этот код, а затем динамически добавляю и удаляю пользовательский пользовательский контроль (MyControl), это то, что его таймер продолжает тикать (в этом примере вы можете видеть, как он записывает сообщение в окне вывода), и он продолжает делать работу в своемтик событие.Какой шаблон следует использовать, чтобы хотя бы таймер прекратил тикать при удалении элемента управления?

Ответы [ 2 ]

5 голосов
/ 05 февраля 2011

Вы можете подключиться к событию Unloaded вашего элемента управления и вызвать timer.Stop() внутри. Я только что протестировал этот сценарий, и событие Unloaded вызывается при вызове anyControlHolder.Children.Clear(), таким образом останавливая отладочные сообщения.

Код:

public partial class MyControl  : UserControl {
    private DispatcherTimer timer;

    public MyControl() {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MyControl_Loaded);
        this.Unloaded += new RoutedEventHandler(MyControl_Unloaded);
    }

    void MyControl_Loaded(object sender, RoutedEventArgs e) {
        timer = new DispatcherTimer();
        timer.Tick += TimerOnTick;
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Start(); 
    }

    void MyControl_Unloaded(object sender, RoutedEventArgs e) {
        timer.Stop();
    }

    private void TimerOnTick(object sender, EventArgs args) {
        Debug.WriteLine("Tick From MyControl.");
    }
}

Надеюсь, это поможет!

2 голосов
/ 05 февраля 2011

Еще одна вещь, которую я бы хотел удалить, - удалить обработчик событий, который вы добавили для своего тикового события.Все, что вы добавляете вручную, вы должны удалить.
Что касается реализации WeakEventPattern, вы можете посмотреть эту статью

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