Как сделать рабочие кнопки в TabItem-е для добавления/удаления TabItem-ов?

Рейтинг: 0Ответов: 0Опубликовано: 27.02.2023

Разбираюсь с WPF, .NET-7. Пытаюсь сделать что-то типа меню с табами, стараюсь реализовать через TabControl, в котором возможно будет динамически добавлять и удалять определённые TabItem-ы. Шаблон итемов сделал, чтобы при добавлении добавлялись кнопки, сейчас пытаюсь через команды их добавлять и удалять, но так работает только с нижними кнопками добавления/удаления, но только не работает удаление, хотя команда срабатывает. В чём проблема и как лучше реализовать данную задачу?

TabModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace TestProject
{
public class TabModel: INotifyPropertyChanged
{
    private string title;

    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            OnPropertyChanged("Title");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
  }
}

ApplicationViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace TestProject
{
public class ApplicationViewModel : INotifyPropertyChanged
{
    private TabModel selectedTab;

    public ObservableCollection<TabModel> Tabs { get; set; }

    private RelayCommand addCommand;
    public RelayCommand AddCommand
    {
        get
        {
            return addCommand ??
              (addCommand = new RelayCommand(obj =>
              {
                  MessageBox.Show("add tab");
                  TabModel tab = new TabModel{ Title = "New Tab" };
                  Tabs.Add(tab);
                  SelectedTab = tab;
              }));
        }
    }

    private RelayCommand removeCommand;
    public RelayCommand RemoveCommand
    {
        get
        {
            return removeCommand ??
              (removeCommand = new RelayCommand(obj =>
              {
                  MessageBox.Show("remove tab");
                  TabModel tab = obj as TabModel;
                  if (tab != null)
                  {
                      Tabs.Remove(tab);
                  }
              },
             (obj) => Tabs.Count > 0));
        }
    }
   
    public TabModel SelectedTab
    {
        get { return selectedTab; }
        set
        {
            selectedTab = value;
            OnPropertyChanged("SelectedTab");
        }
    }

    public ApplicationViewModel()
    {
        Tabs = new ObservableCollection<TabModel>
        {
            new TabModel { Title="Tab 1" },
            new TabModel { Title="Tab 2" },
            new TabModel { Title="Tab 3" },
            new TabModel { Title="Tab 4" }
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
  }
}

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestProject
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new ApplicationViewModel();
        }
    }
}

RelayCommand.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace TestProject
{
    public class RelayCommand : ICommand
    {
        private Action<object> execute;
        private Func<object, bool> canExecute;

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

        public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return this.canExecute == null || this.canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            this.execute(parameter);
        }
    }
}

MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestProject"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TabControl Grid.Column="0" SelectedItem="{Binding SelectedTab}" ItemsSource="{Binding Tabs}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Title}"/>
                        <Button Command="{Binding AddCommand}" Content="+"/>
                        <Button Command="{Binding RemoveCommand}"
                                CommandParameter="{Binding SelectedTab}"
                                Content="-"/>
                    </StackPanel>
                </DataTemplate>
            </TabControl.ItemTemplate>

        </TabControl>
        
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Command="{Binding AddCommand}"
                    Width="50"
                    Height="50">+</Button>
            <Button Command="{Binding RemoveCommand}"
                    CommandParameter="{Binding SelectedPhone}"
                    Width="50"
                    Height="50">-</Button>
        </StackPanel>
    </Grid>
</Window>

Ответы

Ответов пока нет.