【C# WPF】削除ボタンでタブを削除する

今回は、C# WPF で削除ボタンでタブを削除する方法を説明します。

前回は追加ボタンでタブの複製をしました。その続きとなります。

【C# WPF】追加ボタンでタブを複製する方法

2020.02.29
やりたいこと
  • タブのヘッダーに削除ボタン「×」を追加
  • ボタンを押したときタブを削除


上の図のように、タブ2の削除ボタンを押すと、タブ2が削除されるようにします。

開発環境
  • Windows10
  • Microsoft Visual Studio Community2019
  • .NET Framework 4.7.2
  • WPF アプリ( .NET Framework )

タブのヘッダーにユーザーコントロールを使用する

前回は、タブのコンテンツの部分にユーザーコントロールを使用しました。今回はタブのヘッダーもユーザーコントロールを使用します

ユーザーコントロールの使用方法はこちらの記事を参考に。

ヘッダー用に、ユーザーコントロールを作成しました。xamlは以下の通りです。

<UserControl x:Class="TabAddDelTest.TabHeaderUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:TabAddDelTest" mc:Ignorable="d" Height="25" Width="85">
    <Grid>
        <Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Width="60" Height="25"/>
        <Button Content="×" Margin="60,0,0,0" VerticalAlignment="Top" Height="25" Click="ClickedDelete"/>

    </Grid>
</UserControl>

ラベルとボタンがあります。このボタンが削除ボタンです。

デザイナで表示すると↑のようになります。これがタブのヘッダー部分になります。

次にユーザーコントロールのソースコードです。

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 TabAddDelTest
{
    /// 
<summary>
    /// TabHeaderUserControl.xaml の相互作用ロジック
    /// </summary>

    public partial class TabHeaderUserControl : UserControl
    {
        public TabHeaderUserControl()
        {
            InitializeComponent();
        }

        public TabHeaderUserControl(int num)
        {
            InitializeComponent();

            label.Content = "タブ" + num;
        }

        private void ClickedDelete(object sender, RoutedEventArgs e)
        {
            TabItem item = (TabItem)this.Parent;
            TabControl tabControl = (TabControl)item.Parent;

            // 1つ前のタブを選択する
            tabControl.SelectedIndex--;

            // タブを削除する
            tabControl.Items.Remove(item);
        }
    }
}

 

TabHeaderUserControl(int num) コンストラクタは、タブが複製されるときに呼ばれます。タブのヘッダーの文字を設定します。

ClickedDelete メソッドは、削除ボタンを押したときに呼ばれます。ここでは、選択されたタブの削除を行います。

Removeでタブを削除する前に、SelectedIndexで1つ前のタブを選択状態にします。これをしないと、追加ボタンの1つ前のタブを削除しようとしたとき、タブが複製されてしまします

  1. タブを削除した後、追加ボタンのタブが選択状態となる。
  2. MainWindow のSelectedAddDelTab関数( タブの切り替えをした時に呼ばれる関数 ) が呼ばれる。
  3. 追加ボタンを選択したとみなされタブが複製される。

これを防ぐため、あらかじめ1つ前のタブを選択しておかなければいけません。

すなわち、以下のように、タブが1つだけの場合、削除できず自動的に新しいタブができます。

タブ1の削除ボタンを押すと、

タブ2が表示されます。

ここの動作をどうするかについては、ここでは言及しません。

メインウインドウの処理も変更する

前回は追加ボタンでタブの複製からコードを変更しました。

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 TabAddDelTest
{
    /// 
<summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>

    public partial class MainWindow : Window
    {
        // 追加したタブの総数
        private int tabNum = 1;

        public MainWindow()
        {
            InitializeComponent();

            // 先頭のタブの設定
            TabItem item = (TabItem)TabControlAddDel.Items.GetItemAt(0);
            item.Header = new TabHeaderUserControl(tabNum); 
            item.Content = new TabItemUserControl(tabNum);
        }

        private void SelectedAddDelTab(object sender, SelectionChangedEventArgs e)
        {
            // 選択したタブのインデックス
            int idx = TabControlAddDel.SelectedIndex;

            // タブの総数
            int count = TabControlAddDel.Items.Count;

            // 追加ボタン(+)を選択する
            if (idx == count - 1)
            {
                // タブの総数をインクリメント
                tabNum++;

                // 追加するタブの設定
                TabItem item = new TabItem();
                item.Header = new TabHeaderUserControl(tabNum);
                item.Content = new TabItemUserControl(tabNum);

                // 追加ボタンの前にタブを追加
                TabControlAddDel.Items.Insert(count - 1, item);

                // 追加したタブを選択状態にする
                TabControlAddDel.SelectedIndex = count - 1;
            }
        }
    }
}

変更点
  • タブを複製するとき、先ほど作成した削除ボタンのユーザーコントロールをヘッダーに指定する
  • タブの番号をフィールドに追加する

まとめ

今回は、C# WPF で削除ボタンでタブを削除する方法を説明しました。

ネットでは見つけられない情報だったので、公開させていただきました。

開発の参考にしていただければ、嬉しく思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です