简体   繁体   English

使用MVVM删除与所选控件不同的TabControl选项卡

[英]Remove TabControl Tab different than the selected one with MVVM

I have a Tabcontrol on my MainWindow to display child views. 我在MainWindow上有一个Tab控件以显示子视图。 On the ItemTemplate I Add a button to close every tab and SelectedItem and ItemSource are Binded to propertys of my viewModel (SelectedTab and Tabs). 在ItemTemplate上,我添加一个按钮以关闭每个选项卡,并且SelectedItem和ItemSource绑定到viewModel的属性(SelectedTab和Tabs)。 When the close button is executed I call an ICommand from VM to close the tab. 当执行关闭按钮时,我从VM调用ICommand以关闭选项卡。

This is an extract of MainWindow.XAML 这是MainWindow.XAML的摘录

    <TabControl Grid.Row="1" Grid.Column="1" BorderThickness="0" Name="TabViews" Background="Transparent" ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="2" Orientation="Horizontal" Background="Transparent">
                    <TextBlock FontSize="18" Text="{Binding Header}" Margin="0 0 10 0"/>
                    <Button Content="X" 
                        Command="{Binding RelativeSource=
                        {RelativeSource FindAncestor,
                        AncestorType={x:Type TabControl}},
                        Path= DataContext.CloseTabCommand}"                                                            
                        Width="25" Height="25" FontFamily="Verdana" FontWeight="UltraBold" Background="Transparent" FontSize="10"/>
                </StackPanel>                    
            </DataTemplate>
        </TabControl.ItemTemplate>            
    </TabControl>

This is an extract of my viewModel: 这是我的viewModel的摘录:

public ICommand CloseTabCommand
    {
        get
        {
            if (_closeTabCommand == null)                
                _closeTabCommand = new RelayCommand(param => this.CloseTab(), null);
            return _closeTabCommand;
        }            
    }

private void CloseTab()
    {
        this.Tabs.Remove(this.SelectedTab);
    }

public MyTabItem SelectedTab
    {
        get
        {
            return _selectedTab;
        }
        set
        {
            _selectedTab = value;                
            OnPropertyChanged("SelectedTab");
        }
    }

As you can see i'm ussing (I know this is wrong): 如您所见,我正在使用(我知道这是错误的):

this.Tabs.Remove(this.SelectedTab);

That refears to the current selected tab. 表示当前选择的选项卡。 But if i click the button from a tab different than the selected the command is executed anyway and remove the selected tab instead of the clicked one. 但是,如果我从不同于选定选项卡的选项卡中单击按钮,则无论如何都会执行该命令,并删除选定的选项卡,而不是单击的选项卡。 So my question is how can i get a reference for the clicked tab button instead of the selected one so I can removeit from my collection? 所以我的问题是我如何才能获得有关单击的选项卡按钮而不是所选按钮的引用,以便可以将其从收藏夹中删除? Maybe a command parameter form XAML with a reference to clicked tab? 也许来自XAML的命令参数引用了clicked选项卡? Thanks! 谢谢!

UPDATE 更新

I got it working thanks to @Rohit Vats help. 多亏@Rohit Vats的帮助,我才能正常工作。 Now i'm tryn to call the same command but from a different XAML usercontrol, loaded inside a conterpresenter on the TabControl: 现在,我尝试从不同的XAML用户控件调用相同的命令,该控件加载在TabControl的conterpresenter中:

<TabControl Grid.Row="1" Grid.Column="1" BorderThickness="0" Name="TabViews" Background="Transparent" ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="2" Orientation="Horizontal" Background="Transparent">
                    <TextBlock FontSize="18" Text="{Binding Header}" Margin="0 0 10 0"/>
                    <Button Style="{DynamicResource MetroCircleButtonStyle}" Content="X" 
                        Command="{Binding RelativeSource=
                        {RelativeSource FindAncestor,
                        AncestorType={x:Type TabControl}},
                        Path= DataContext.CloseTabCommand}"      
                        CommandParameter="{Binding}"
                        Width="25" Height="25" FontFamily="Verdana" FontWeight="UltraBold" Background="Transparent" FontSize="10"/>
                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentPresenter Grid.Row="1" Grid.Column="1" x:Name="ContentArea" Content="{Binding Content}"/>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

This is the code for the button on Client view: 这是“客户端”视图上的按钮的代码:

<Button Name="cmdCerrar" Grid.Row="0" Grid.Column="5" Margin="5"
                     Command="{Binding RelativeSource=
                        {RelativeSource FindAncestor,
                        AncestorType={x:Type TabControl}},
                        Path= DataContext.CloseTabCommand}"      
                        CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}"
                    >Cerrar</Button>

And this is the code i use on MainWIndow ViewModel to créate the child view: 这是我在MainWIndow ViewModel上创建子视图的代码:

public ICommand CreateViewsCommand
    {
        get
        {
            if(_createViewsCommand==null)
                _createViewsCommand = new RelayCommand(
                    (classtype) => 
                    {
                        if (classtype != null)
                        {
                            bool bFound=false;
                            foreach (MyTabItem myTab in _tabs)                                
                            {
                                if (myTab.Content.GetType().ToString() == classtype.ToString())
                                {
                                    bFound = true;
                                    SelectedTab = myTab;
                                }
                            }
                            if (!bFound) CreateView = (UserControl)Activator.CreateInstance(classtype as Type);                               
                        }
                    });                
            return _createViewsCommand;
        }            
    }

 public UserControl CreateView
    {
        get
        {
            return _createView;
        }
        set
        {
            if (value != _createView)
            {
                _createView = value;
                var myTab = new MyTabItem { Header = value.GetType().Name, Content = value };
                Tabs.Add(myTab);
                this.SelectedTab = myTab;
                OnPropertyChanged("CreateView");
            }
        }
    }

And by last this is the command i want to call: 最后,这是我要调用的命令:

 private void CloseTab(object param)
    {
        MyTabItem tabItem = (MyTabItem)param;
        this.Tabs.Remove(tabItem);            
    }

When i call it from a button on MainWindow it Works. 当我从MainWindow上的按钮调用它时,它将起作用。 But from child window, param get null. 但是在子窗口中,param变为null。 Any ideas? 有任何想法吗?

Pass DataContext as CommandParameter which will point to the object instance of TabItem on which button is clicked. DataContext作为CommandParameter传递,它将指向单击了按钮的TabItem的对象实例。

<Button Content="X" 
        Command="{Binding RelativeSource= {RelativeSource FindAncestor,
                        AncestorType={x:Type TabControl}},
                        Path= DataContext.CloseTabCommand}"
        CommandParameter="{Binding}"
        Width="25" Height="25" FontFamily="Verdana" FontWeight="UltraBold" 
        Background="Transparent" FontSize="10"/>

and pass parameter to command method and remove the passed value from the source collection instead of selected tab: 并将参数传递给命令方法,并从源集合而不是选定的选项卡中删除传递的值:

public ICommand CloseTabCommand
{
    get
    {
        if (_closeTabCommand == null)                
            _closeTabCommand = new RelayCommand(param => this.CloseTab(param),
                                                         null);
        return _closeTabCommand;
    }            
}

private void CloseTab(object param)
{
    TabItem tabItem = (TabItem)param;
    this.Tabs.Remove(tabItem);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM