TabItem上的关闭按钮不起作用 [英] Doesn't work close button on the TabItem

查看:108
本文介绍了TabItem上的关闭按钮不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,所有



我正在使用WPF和MVVM模式,我尝试创建可关闭的tabitem控件。但我在tabitem模板中的按钮上的绑定方法CloseCommand不起作用。适用于窗口中的任何按钮。我不明白,为什么?下面是测试项目的代码。



谢谢。



ViewModel

namespace CloseableTabControl.ViewModel
{
    public class CloseableTabControlVM
    {
        private RelayCommand _closeCommand;
        public ICommand CloseCommand
        {
            get {
                if (_closeCommand == null )
                _closeCommand = new RelayCommand(param => this.closeButton_Execute());

                return _closeCommand;
            }
        }
        
        private ObservableCollection<IPageBase> _pages;

        public ObservableCollection<IPageBase> Pages
        {
            get { return _pages; }
            set { _pages = value; }
        }


        public CloseableTabControlVM()
        {
            _pages = new ObservableCollection<IPageBase>();
            _pages.Add(new TabItem1VM());
            _pages.Add(new TabItem2VM());
            _pages.Add(new TabItem1VM());
        }

        private bool closeButton_canExecute() { return true; }

        private void closeButton_Execute() 
        {
            MessageBox.Show("Click me!");
        }
    }
}





命令



Commands

namespace CloseableTabControl.Command
{
    public class RelayCommand : ICommand
    {

        #region Fields
        private readonly Predicate<object> _canExecute;
        private readonly Action<object> _execute;
        #endregion

        #region Constructor
        public RelayCommand(Action<object> execute):this(null, execute) { }

        public RelayCommand(Predicate<object> canExecute, Action<object> execute)
        {
            if (execute == null) throw new ArgumentNullException("execute");
            _execute = execute;
            _canExecute = canExecute;
        }
        #endregion

        [DebuggerStepThrough]
        public bool CanExecute(object param)
        {
            return _canExecute == null ? true : _canExecute(param); 
        }

        public void Execute(object param)
        {
            _execute(param);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}





MainWindow代码

namespace CloseableTabControl
{
    public partial class MainWindow : Window
    {
        private CloseableTabControlVM _closeTab;
        public CloseableTabControlVM CloseTab
        {
            get { return _closeTab; }
            set { _closeTab = value; }
        }

        public MainWindow()
        {
            _closeTab = new CloseableTabControlVM();
            InitializeComponent();
        }
    }
}





和MainVindow XAML



And MainVindow XAML

<Window x:Class="CloseableTabControl.MainWindow"

        x:Name="MainWindowInstance"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:v="clr-namespace:CloseableTabControl.View"

        xmlns:vm="clr-namespace:CloseableTabControl.ViewModel"

        DataContext="{Binding CloseTab,ElementName=MainWindowInstance}"

        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:TabItem1VM}">
            <v:TabItem1/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:TabItem2VM}">
            <v:TabItem2/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <TabControl 

            HorizontalAlignment="Left"

            VerticalAlignment="Top"

            Margin="10,10,10,10"

            Width="500"

            Height="300"

            ItemsSource="{Binding Pages}">
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="HeaderTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Header}"/>
                                    <Button Content="x" Margin="0" Command="{Binding CloseCommand}" Width="16" Height="16"/>
                                </StackPanel>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>
    </Grid>
</Window>

推荐答案

如果在调试时查看输出窗口,则表示 ll看到你有关于CloseCommand的绑定错误,说明它不属于相关的VM。那是因为你的命令没有在VM级别定义 - 而是在容器级别定义。要解决此问题,请使用相对源来查找包含此内容的选项卡项 - 并绑定到该DataContext,如下所示:
If you look in your Output window when debugging, you''ll see that you have binding errors in there relating to the CloseCommand, stating that it doesn''t belong to the relevant VM. That''s because your command isn''t defined at the VM level - rather, it''s defined at the container level. To fix this, use the relative source to find the tab item that contains this - and bind to that DataContext, like this:
<Button Content="x" Margin="0" Command="{Binding DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Width="16" Height="16"/>


这篇关于TabItem上的关闭按钮不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆