1

我有一个用标签组织的 WPF 应用程序。我在每个 tabitem 标题中添加了一个小按钮,允许用户关闭选项卡。

当用户单击小按钮时,我从 tabControl 中删除了 tabItem。

tabControl.Items.Remove(tabItem);

结果 tabItem 消失了,这很好,但问题来了:

TabItem 不可见(好),但它仍然存在(坏)。如果我在里面放了一个计时器,计时器会执行他的 Tick,更重要的是,如果我有一个包含 200.000 条记录的数据网格并且我关闭了选项卡,那么垃圾收集器不会像我预期的那样释放内存。

我向谷歌询问了这个问题,并且我已经实施了一些描述的建议。它没有用。

谁能帮我?谢谢

4

2 回答 2

1

这是我一直在使用的,据我所知,它从记忆中删除了 tabitem。将计时器留在 tabitem 中的问题是 GC 不会收集和处理它,因为它检测到计时器仍在使用中。

编码:

namespace Reports.Controls
{
    /// <summary>
    /// Interaction logic for Test.xaml
    /// </summary>
    public partial class ReportTab : TabItem
    {
        public delegate void CloseEvents(ReportTab TabIndex);
        public event CloseEvents Closing;

        public ReportTab(string Title)
        {
            InitializeComponent();
            tbTitle.Text = Title;
        }

        private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Closing(this);
        }
    }
}

xml:

<TabItem x:Class="Reports.Controls.ReportTab"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <TabItem.Header>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Main" Name="tbTitle" Margin="0,0,8,0"/>
            <Image Height="13" 
                   Source="pack://application:,,/Images/Icons/close.png"
                   MouseLeftButtonUp="Image_MouseLeftButtonUp"/>
        </StackPanel>
    </TabItem.Header>
    <Grid>
         //Tabitem stuff
    </Grid>
</TabItem>

这是带有 Tabcontrol 以添加选项卡的页面:

void AddTab(string Title)
{
    Controls.ReportTab rt = new Controls.ReportTab(Title);
    rt.Closing += new Controls.ReportTab.CloseEvents(rt_Closing);
    tabControl.SelectedIndex = tabControl.Items.Add(rt);
}

/// <summary>
/// Moves the Tab Control back to the Main tab
/// after a tab is removed
/// </summary>
/// <param name="TabIndex"></param>
void rt_Closing(Controls.ReportTab TabIndex)
{
    tabControl.Items.Remove(TabIndex);
    //This resets the tabcontrol back to it's first tabindex
    tabControl.SelectedIndex = 0;

}
于 2009-04-09T21:04:18.823 回答
0

在您的选项卡中放置一个用户控件,并在 Usercontrol 代码中处理它自己的“Unloaded”事件。

在那里你应该能够清理。(除非您的计时器阻止控件卸载,但上次我尝试了类似的方法)。

是的,WPF 对所有这些事情都是非常危险的,如果你不小心,你可以很快地流血控制......

于 2009-04-09T20:59:36.430 回答