我已经在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.");
}
}
Run Code Online (Sandbox Code Playgroud)
这是添加和删除我的控件的窗口背后的代码.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我运行此代码然后动态添加和删除自定义usercontrol(MyControl)时遇到的问题是它的计时器一直在滴答作响(在这个例子中你可以看到它在输出窗口中写出一条消息)并且它一直在做在它的tick事件中工作.我应该使用什么模式来至少导致计时器在删除控件时停止滴答?
你可以挂钩你的控件的Unloaded事件并timer.Stop()在里面调用.我刚测试了这个场景,并在anyControlHolder.Children.Clear()调用时引发了Unloaded事件,从而停止了调试消息.
码:
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.");
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!