我正在逐步向我的程序中的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#;因为我没有。
答案 0 :(得分:1)
通常,WPF在从视口中删除时不会丢弃用户控件。这会导致某些应用程序出现问题(请参阅Disposing WPF User Controls进行广泛的讨论)。
要解决更具体的问题(例如停止计时器),请处理Unloading
上的TabItem
事件,并在那里停用计时器(http://msdn.microsoft.com/en-us/library/system.windows.controls.tabitem(v=vs.110).aspx)。
这是一个高级示例(子类化TabItem
仅作为封装计时器的示例):
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
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
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <filterpriority>2</filterpriority>
public void Dispose()
{
MyTimer.Stop();
MyTimer.Tick -= TimerOnTick;
MyTimer = null;
}
#endregion
}