かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[C#][WPF]コマンドですね その2「GUIにコマンドを結びつける」

その1「ICommandインターフェース」:http://blogs.wankuma.com/kazuki/archive/2008/03/16/127903.aspx

その1で、ICommandインターフェースとコンソールアプリで実装したクラスを使うところまでやってみた。
正直、あんな風には使わずにWPFで提供されているICommandを実装したクラスや、もっといい方法を使ったりする。
今回で、一般的なWPFでのコマンドの使い方くらいまで紹介できたらいいなと考えてる。

今回は、GUIでコマンドを使ってみる。
ボタンを押すと世界中のプログラマが見たことある「こんにちは世界」を表示するという素敵なアプリケーションを作ってみようと思う。
実行結果すると丁度下のような画面になるものだ。

image

ということで、早速コマンドを実装してみようと思う。
実装は、解説がいらないくらいシンプル。

using System;
using System.Windows;
using System.Windows.Input;

namespace WpfCommand
{
    public class HelloCommand : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            MessageBox.Show("こんにちは世界");
        }
    }
}

この調子でサクサクとXAMLも定義していく。StackPanelにボタンを乗せるだけでOK。一応ボタンクリックの時のイベントも定義してある。

<Window x:Class="WpfCommand.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="コマンド" Height="300" Width="300">
    <StackPanel>
        <Button Content="Click!" Click="Button_Click" />
    </StackPanel>
</Window>

そして、ボタンクリックのイベントのあるWindow1.xaml.csは、こんな感じ。

using System.Windows;
using System.Windows.Input;

namespace WpfCommand
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ICommand command = new HelloCommand();
            if (command.CanExecute(null))
            {
                command.Execute(null);
            }
        }
    }
}

コマンドが実行可能かどうか尋ねて実行してる。
これをベースに、改造していく。

とりあえず、今コマンドをボタンクリックの中でインスタンス化してる。
普通は、コマンドってショートカットから実行されたり、メニューから実行されたり、ツールバーのボタンから実行されたり、さまざまな所から実行される。
なので、各々のイベントでインスタンスを作るのは無駄っぽい。
ICommandインターフェースは、実行に必要な情報を引数から受け取る実装をすることが多そうなので、大体ステートレスになりそうだ。
ということで、Window1のstaticでreadonlyな定数として定義する。

using System.Windows;
using System.Windows.Input;

namespace WpfCommand
{
    public partial class Window1 : Window
    {
        // 皆から使えるようにstatic readonlyで定義
        static readonly ICommand HelloCommand = new HelloCommand();

        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // 定数として定義したものを使う
            if (HelloCommand.CanExecute(null))
            {
                HelloCommand.Execute(null);
            }
        }
    }
}

これでメニューとかから実行する場合も、if (HelloCommand.CanExecute(null)) HelloCommand.Execute(null);を書くだけでOKだ。
でも、まだ毎回同じコードを書くことになってしまう。
そうならないように、WPFでコマンドと関連付けそうなコントロールには、Commandプロパティというものが定義されてる。
これを使うとWindow1.xamlとWindow1.xaml.csは下のようになる。

<Window x:Class="WpfCommand.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="コマンド" Height="300" Width="300">
    <StackPanel>
        <Button Name="button" Content="Click!" />
    </StackPanel>
</Window>
using System.Windows;
using System.Windows.Input;

namespace WpfCommand
{
    public partial class Window1 : Window
    {
        // 皆から使えるようにstatic readonlyで定義
        static readonly ICommand HelloCommand = new HelloCommand();

        public Window1()
        {
            InitializeComponent();
            button.Command = HelloCommand;
        }
    }
}

これで、初期化のコードに、このボタンはこのコマンドを実行しますという事を書くだけでOKになる。
だいぶすっきりした。
こういう風に宣言的に書くコードはXAMLに移動させることが出来る。

<Window x:Class="WpfCommand.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfCommand="clr-namespace:WpfCommand"
    Title="コマンド" Height="300" Width="300">
    <StackPanel>
        <Button Name="button" Content="Click!" Command="{x:Static WpfCommand:Window1.HelloCommand}"/>
    </StackPanel>
</Window>

変わったのは、4行目の名前空間の宣言と、7行目のボタンのCommandプロパティの設定になる。
x:Staticを使ってWindow1のHelloCommandを設定するようにしてある。

Window1.xaml.csのほうは下のようになった。

using System.Windows;
using System.Windows.Input;

namespace WpfCommand
{
    public partial class Window1 : Window
    {
        // 外部から見えるようにpublicへ
        public static readonly ICommand HelloCommand = new HelloCommand();

        public Window1()
        {
            InitializeComponent();
        }
    }
}

これでWPFが提供している仕組みとかを使って素敵な感じになってきた。
ICommandインターフェースを実装してバリバリ書いていくぜ!!となりそうだけど、実際はRoutedCommandクラスとかを使うことになる。
それはまた別の話しで。

投稿日時 : 2008年3月16日 10:39

Feedback

# [C#][WPF]コマンドですね その3「ショートカットとコマンドを結びつける」 2008/03/16 10:55 かずきのBlog

[C#][WPF]コマンドですね その3「ショートカットとコマンドを結びつける」

# [C#][WPF]コマンドですね その5「RoutedCommand」 2008/03/16 11:27 かずきのBlog

[C#][WPF]コマンドですね その5「RoutedCommand」

# louis vuitton outlet store 2012/10/28 3:21 http://www.louisvuittonbackpack2013.com/

Simply because a friend or relative doesn‘longer love you the way we long for them to actually,doesn‘longer necessarily mean that they have on‘longer love you with all of they offer.
louis vuitton outlet store http://www.louisvuittonbackpack2013.com/

# louis vuitton speedy 2012/10/28 3:21 http://www.louisvuittonoutletdiaperbag.com/

Have on‘l look into over-time, the right features show up after you least expect to see these phones.
louis vuitton speedy http://www.louisvuittonoutletdiaperbag.com/

# louis vuitton shoes 2012/10/28 3:21 http://www.louisvuittonwallets2013.com/

Through prosperity all of our buddys be aware all of; throughout adversity we all know all of our buddys.
louis vuitton shoes http://www.louisvuittonwallets2013.com/

# Burberry Watches 2012/10/28 17:18 http://www.burberryoutletonlineshopping.com/burber

I will right away grasp your rss feed as I can not find your email subscription link or e-newsletter service. Do you have any? Kindly allow me know so that I may subscribe. Thanks.
Burberry Watches http://www.burberryoutletonlineshopping.com/burberry-watches.html

# MuCwzUXrUouMyqnIVw 2014/08/05 5:51 http://crorkz.com/

psokrJ wow, awesome blog article.Thanks Again. Want more.

# cZTJLpfkmIabbpIZeag 2014/08/27 23:37 http://crorkz.com/

nAimHL excellent points altogether, you just won a brand new reader. What may you suggest in regards to your put up that you made some days in the past? Any certain?

タイトル  
名前  
Url
コメント