WPF移除选项卡不会释放内容?
WPF移除选项卡不会释放内容?
我在程序中动态地向TabControl
添加选项卡。每个选项卡的内容都是使用UserControl
填充的:
private void process_addTab(string head, string type) { TabItem tab = new TabItem(); tab.Header = head; switch (type) { case "trophy2": tab.Content = new Scoreboard2(); break; case "trophy4": tab.Content = new Scoreboard4(); break; case "text": tab.Content = new TextFields(); break; case "talk": tab.Content = new LowerThirds(); break; case "image": tab.Content = new ImageSelect(); break; case "timer": tab.Content = new Timer(); break; case "hitbox": tab.Content = new Hitbox(); break; case "twitch": tab.Content = new Twitch(); break; case "twitter": tab.Content = new Twitter(); break; case "ustream": tab.Content = new Ustream(); break; } tabControl.Items.Add(tab); }
这很好地运作。但是,在从TabControl
中删除选项卡时会出现问题。每个选项卡都有一个按钮,可以将特定的选项卡从控件中删除:
public static void RemoveClick(TabControl tabControl) { if (MessageBox.Show("Are you sure you wish to remove this tab?", "Remove Tab", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) { TabItem item = (TabItem)tabControl.SelectedItem; tabControl.Items.Remove(tabControl.SelectedItem); } }
这也看起来工作得很好,因为选项卡已被移除。然而,这有点欺骗性。在一些控件中,我有一个DispatcherTimer
定时运行的函数。例如,Twitch控件在控件内部具有一个定时器,每30秒轮询Twitch API以获取频道信息。如果我删除选项卡,定时器仍然继续运行;即使它不应该存在了。
有什么办法可以解决这个问题吗?假设我不太了解C#,因为我确实不太了解。
admin 更改状态以发布 2023年5月23日
通常情况下,当WPF从视口中移除用户控件时,它不会将其释放。这会在一些应用程序中造成麻烦(有关更广泛的讨论,请参见释放WPF用户控件)。
要解决您更具体的问题(例如停止计时器),请处理TabItem
上的Unloading
事件,在那里禁用计时器(请参见https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.tabitem)。
这是一个高级示例(子类化TabItem
只是为了演示封装定时器):
////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); TimerTabItem item = new TimerTabItem(); item.Unloaded += ItemOnUnloaded; tabControl.Items.Add(item); } private void ItemOnUnloaded(object sender, RoutedEventArgs routedEventArgs) { (sender as TimerTabItem).Dispose(); } private void Button_Click(object sender, RoutedEventArgs e) { tabControl.Items.Remove(tabControl.Items[0]); } } class TimerTabItem : TabItem, IDisposable { private DispatcherTimer MyTimer { get; set; } public TimerTabItem() : base() { DispatcherTimer timer = new DispatcherTimer(); timer.Interval = new TimeSpan(0, 0, 0, 3); timer.Tick += TimerOnTick; timer.Start(); MyTimer = timer; } private void TimerOnTick(object sender, EventArgs eventArgs) { MessageBox.Show("Hello!"); } #region Implementation of IDisposable ////// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// ///2 public void Dispose() { MyTimer.Stop(); MyTimer.Tick -= TimerOnTick; MyTimer = null; } #endregion }