【问题标题】:Problems closing tabs关闭标签的问题
【发布时间】:2009-04-09 20:33:24
【问题描述】:

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

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

tabControl.Items.Remove(tabItem);

因此,tabItem 消失了,这很好,但问题来了:

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

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

谁能帮帮我? 谢谢

【问题讨论】:

    标签: wpf memory wpf-controls


    【解决方案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);
            }
        }
    }
    

    xaml:

    <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>
    

    这是带有用于添加选项卡的 Tab 控件的页面:

    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;
    
    }
    

    【讨论】:

      【解决方案2】:

      在标签中放置一个用户控件,并在用户控件代码中处理它自己的“Unloaded”事件。

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

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

      【讨论】:

        猜你喜欢
        • 2012-10-25
        • 1970-01-01
        • 2011-05-12
        • 1970-01-01
        • 2022-06-13
        • 2018-10-21
        • 1970-01-01
        相关资源
        最近更新 更多