我有一个带有splitviewcontainer的简单表单,左边是菜单,右边是一个或多个控件。
可以在RHS上加载的其中一个控件包含一个计时器,用于每隔几秒刷新一次数据。
如果我在右侧使用Controls.Clear(),控件将不再显示,但我认为它尚未处理,因为计时器仍在触发(我可以看到数据库调用是在日志中进行的) )。
我的问题是,当我的控件从显示中移除后,我应该如何清理它?清除控件时调用哪个事件/方法?
答案 0 :(得分:2)
您应该在控件上调用相应的Dispose()
方法。
您可以使用扩展方法执行此操作,请参阅Hans Passant的this回答。
可以在RHS上加载的其中一个控件包含一个计时器,用于每隔几秒刷新一次数据。
现在,你可能会遇到竞争条件。当您调用尚未创建的Clear()
扩展方法时,计时器可能会进行回调。如果您的计时器回调函数可能会导致应用程序中的数据损坏,您将不得不这样做。
Timer.Stop();
Timer.Tick -= Timer_Tick(TimerCallback);
Timer.Dispose();
现在另一个问题是 - 您是否可以隐藏这些控件?是否存在妨碍您这样做的约束?
答案 1 :(得分:1)
这段代码应该工作
public Form1()
{
InitializeComponent();
UserControl cc = new UserControl();
Panel pp = new Panel();
pp.Controls.Add(cc);
pp.ControlRemoved += new ControlEventHandler(pp_ControlRemoved);
pp.Controls.Clear();
}
void pp_ControlRemoved(object sender, ControlEventArgs e)
{
var control = sender as MyVerySpecialControl;
if (control != null)
{
//stop timers or unassign events
}
}
我很乐意回答任何疑问
答案 2 :(得分:0)
我会使用扩展方法而不是Clear()。并循环访问子控件并专门处理它们。如果有没有IDispose(但应该有)的certaion控件导致这种情况,那么你可以在循环中专门捕获它们并调用任何方法来阻止它们,然后再用最后的清除它们。