自定义TabItem:关闭时可关闭选项卡和释放内存

时间:2012-05-03 19:39:34

标签: xaml mvvm

自定义TabItem

我有一个TabControl绑定到我的ViewModel我也想删除标签,但我看不到这些标签,tabitems看到默认没有更改

    <TabControl
        Margin="5 5 5 0"
        Grid.Row="1"
        ItemsSource="{Binding Path=ListTabItem}"
        SelectedIndex="{Binding Path=CurrentTabItemIndex}"
        x:Name="Workspace" Background="White">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <cmd:EventToCommand
                Command="{Binding ChangeTabCommand}"
                CommandParameter="{Binding SelectedItem, ElementName=Workspace}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <!--Here is my tabHeader-->
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Header}" />                        
                    <Button Content="X" Command={Binding CloseTabCommand}
                      CommandParameter="{Binding SelectedItem, ElementName=Workspace}"/>
                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>            
    </TabControl>

编辑:

我得到了一种工作方式,但是当关闭标签不释放内存时我遇到了问题:

    <Style x:Key="HeaderTabItem" TargetType="TabItem">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Button                                
                            Width="20"
                            Height="20"
                            Margin="-3 0 5 0"
                            Padding="2"
                            HorizontalAlignment="Left"
                            VerticalAlignment="Center"
                            BorderBrush="{x:Null}" Background="{x:Null}" Foreground="{x:Null}"
                            DataContext="{Binding DataContext, ElementName=Workspace}"
                            Command="{Binding Path=CloseTabCommand}"
                            CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TabItem, AncestorLevel=1}}" Content="X"/>
                        <ContentControl
                            Grid.Column="1" 
                            VerticalAlignment="Center"
                            HorizontalAlignment="Left"
                            Content="{Binding Path=Header, RelativeSource={RelativeSource FindAncestor, AncestorType=TabItem, AncestorLevel=1}}" />
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>

在我的ViewModel

    CloseTabCommand = new RelayCommand<TabItem>(tab =>
    {
        if (null == tab) return;
        ListTabItem.Remove(tab);
    },
    tab =>
    {
        return ListTabItem.IndexOf(tab) == CurrentTabItemIndex;
    });

任何想法?

1 个答案:

答案 0 :(得分:1)

除非他们的DataContext已被清除(这看起来像是一种黑客攻击),否则WPF控件往往不会适当地自行处理。试试这个:

CloseTabCommand = new RelayCommand<TabItem>(tab =>
{
    if (null == tab) return;

    tab.DataContext = null;

    ListTabItem.Remove(tab);
},
tab =>
{
    return ListTabItem.IndexOf(tab) == CurrentTabItemIndex;
});

另外,请注意,您可能看到立即发布的内存。由于垃圾收集在.NET中的工作原理,您的应用程序可能需要等待/其他事件才能实际发生垃圾收集并清除内存。

如果你真的想要,你可以调用GC.Collect(),但如果你不相信内存被释放,我会这样做 我只会将其用于调试并确保释放对象。确认后,将其删除并允许垃圾收集器完成其工作。