C#のメニューのイベントを1つにまとめてみた

アプリにメニューを付けると、メニューの各項目毎にClickイベントのコードを書くことになります。ですが、実は各メニュー項目が同じメソッドを引数を変えて呼び出していたりして、そうすると項目毎にClickイベントを書くのも面倒だなと思うことがあります。

ということで、各メニュー項目から同一のイベントハンドラを呼び出すようにしてみました。

目次

  1. 試してみた
    1. Headerで識別する編
    2. Tagで識別する編

試してみた

Tagで識別する編

Headerプロパティで識別するとコードは短く出来ますが、メニューの表示文字列を変更したときにClickイベントのコードの方も変更しなければならなくなります。これは面倒ですね。 ということで、HeaderではなくTagプロパティを使ってみます。

XAMLを下記のようにします。MenuItem要素にTagという属性を追加しました。

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="200" >
    <Grid>
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="やりましょう">
                    <MenuItem Tag="kore" Header="これ" Click="MenuItem_Click" />
                    <MenuItem Tag="sore" Header="それ" Click="MenuItem_Click" />
                    <MenuItem Tag="are" Header="あれ" Click="MenuItem_Click" />
                    <MenuItem Tag="dore" Header="どれ?" Click="MenuItem_Click" />
                </MenuItem>
            </Menu>
            <TextBlock Name="textblock" />
        </DockPanel>
    </Grid>
</Window>

そして、コードを下記のようにします。MenuItemのインスタンスから、Tagプロパティを取り出して、ToString()で文字列に変換し、switch文で条件分岐します。

using System.Windows;
using System.Windows.Controls;

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

        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            MenuItem menuitem = (MenuItem)sender; // オブジェクトをMenuItemクラスのインスタンスにキャストする。
            string header = menuitem.Header.ToString(); // Headerプロパティを取り出して、文字列に変換する。
            string tag = menuitem.Tag.ToString(); // Tagプロパティを取り出して、文字列に変換する。

            switch (tag) // Tag文字列毎の処理
            {
                case "kore":
                    textblock.Text = textblock.Text + header + "\r\n";
                    break;
                case "sore":
                    textblock.Text = textblock.Text + header + "\r\n";
                    break;
                case "are":
                    textblock.Text = textblock.Text + header + "\r\n";
                    break;
                case "dore":
                    textblock.Text = textblock.Text + header + "\r\n";
                    break;
                default:
                    textblock.Text = textblock.Text + "???" + "\r\n";
                    break;
            }
        }
    }
}

実行結果は、Headerで識別したときと全く同じになります。

この方法なら、ユーザーから見えないTagというプロパティを使って識別するので、メニューの表示文字列(Headerプロパティ)の後からの変更が簡単にできます。

更新日
公開日

広告