WPFでプログラムしてみよう(4)


これからは該当の記事よりも過去分の記事にはインデックスを付けることにします。

    1. WPFでプログラムしてみよう(1)-依存プロパティ等のWPF概要説明-
    2. WPFでプログラムしてみよう(2)-環境作成方法とパネルの使い方-
    3. WPFでプログラムしてみよう(3)描画オブジェクト(その1)-

今回はテキストの前回からの続きで、4章の描画オブジェクトをまとめます。


Windows Presentation Foundation プログラミング入門

Windows Presentation Foundation プログラミング入門

4.4 複数線と多角形

Polygonクラスを使用して閉じた図形を描画してみます。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

class Test {
	[STAThread]
	public static void Main(){
        Polygon pgn = new Polygon();
        pgn.Stroke = Brushes.Black;

        pgn.Points.Add(new Point( 10, 10));
        pgn.Points.Add(new Point(110, 10));
        pgn.Points.Add(new Point(110,210));
        pgn.Points.Add(new Point( 60,210));
        pgn.Points.Add(new Point( 60, 60));
        pgn.Points.Add(new Point(210, 60));
        pgn.Points.Add(new Point(210,160));
        pgn.Points.Add(new Point( 10,160));
        pgn.Points.Add(new Point( 10,130));
        pgn.Points.Add(new Point(130,130));
        pgn.Points.Add(new Point(130, 90));
        pgn.Points.Add(new Point( 10, 90));

        Polygon pgn2  = new Polygon();
        pgn2.Stroke   = Brushes.Gray;
        pgn2.Fill     = Brushes.Pink;
        pgn2.FillRule = FillRule.Nonzero;

        foreach (Point pt in pgn.Points){
            pgn2.Points.Add(new Point(pt.X + 30 , pt.Y));
        }

        Button btnCChange = new Button();
        btnCChange.Width = 200; 
        btnCChange.Content = "押すと赤で塗りつぶします";
		btnCChange.Click += (sender, e) => {
            if (pgn.Fill == null) {
                pgn.Fill  = Brushes.Red;
                pgn2.Fill = Brushes.Red;
                btnCChange.Content = "押すと青で塗りつぶします";
            } else if (pgn.Fill == Brushes.Red) {
                pgn.Fill  = Brushes.Blue;
                pgn2.Fill = Brushes.Blue;
                btnCChange.Content = "押すと塗りつぶしません";
            } else if (pgn.Fill == Brushes.Blue) {
                pgn.Fill  = null;
                pgn2.Fill = null;
                btnCChange.Content = "押すと赤で塗りつぶします";
            }
        };

        StackPanel stpnl = new StackPanel();
        stpnl.Orientation = Orientation.Horizontal;

        stpnl.Children.Add(pgn);
        stpnl.Children.Add(pgn2);
        stpnl.Children.Add(btnCChange);

		Window wnd = new Window();
        wnd.Content = stpnl;

		Application app = new Application();
		app.Run(wnd);
	}
}


これをコンパイルして実行してみます。



画面上に重なり合った図形が2組、表示されます。
細かいことは考えずに、まずは右側に配置されているボタンを一度押してください。




両方赤く塗りつぶされましたが、塗りつぶし方が左右で異なります。
もう一度ボタンを押してみます。



今度は塗りつぶしが青に変わりました。
さらにもう一度ボタンを押してみます。



これで最初の状態に戻りました。あとはこの繰り返しなので気の済むまでボタンを押してみてください。
ポイントはPolygonクラスのインスタンスのFillプロパティには塗りつぶしの色を指定できるということ(nullの場合は塗りつぶしなし)と、塗りつぶしのパターンを帰られるということです。塗りつぶしのパターンはPolygonクラスのプロパティであるFillRule(列挙型)で指定できます。
この列挙型についてはMSDNに詳しく図解されているのでこちらをご覧ください。


4.5 テキスト

単純な文字列はContentControlのContentプロパティに設定すれば表示出来ますが、この場合は細かい制御がまったくできず不便です。
表示している文字列を制御する場合にはTextBlockクラスを利用します。

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

class Test {
	[STAThread]
	public static void Main(){
                TextBlock txtblk = new TextBlock();
                txtblk.Width     = 500;
                txtblk.FontSize  = 20;
                txtblk.Text      = "テスト!!";

                Button btnSetPos = new Button();
                btnSetPos.Width  = 500;
                txtblk.TextAlignment = TextAlignment.Center;
                btnSetPos.Content = "文字を左に配置します";

                btnSetPos.Click += (sender , e) => {
                    if (txtblk.TextAlignment == TextAlignment.Center){
                        txtblk.TextAlignment = TextAlignment.Left;
                        btnSetPos.Content = "文字を右に配置します";

                    } else if (txtblk.TextAlignment == TextAlignment.Left){
                        txtblk.TextAlignment = TextAlignment.Right;
                        btnSetPos.Content = "文字を両端揃えに配置します";

                    } else if (txtblk.TextAlignment == TextAlignment.Right){
                        txtblk.TextAlignment = TextAlignment.Justify;
                        btnSetPos.Content = "文字を中央揃えに配置します";

                    } else if (txtblk.TextAlignment == TextAlignment.Justify){
                        txtblk.TextAlignment = TextAlignment.Center;
                        btnSetPos.Content = "文字を左に配置します";
                    }
                };


                Button btnInline = new Button();
                btnInline.Width  = 500;
                btnInline.Content = "文字の一括追加";

                btnInline.Click += (sender , e) => {
                    txtblk.Inlines.Clear();
                    txtblk.Inlines.Add(              new Run("テスト!!"));
                    txtblk.Inlines.Add(new Bold(     new Run("テスト!!")));
                    txtblk.Inlines.Add(new Italic(   new Run("テスト!!")));
                    txtblk.Inlines.Add(new Underline(new Run("テスト!!")));
                    txtblk.Inlines.Add(new Hyperlink(new Run("テスト!!")));
                };

        	Window wnd = new Window();

	        Canvas cnvs = new Canvas();
                Canvas.SetLeft(txtblk   , 20);
	        Canvas.SetLeft(btnSetPos, 20);
        	Canvas.SetLeft(btnInline, 20);
	        Canvas.SetTop(txtblk   , 20);
        	Canvas.SetTop(btnSetPos, 120);
	        Canvas.SetTop(btnInline, 220);
        	cnvs.Children.Add(txtblk);
	        cnvs.Children.Add(btnSetPos);
        	cnvs.Children.Add(btnInline);

	        wnd.Content = cnvs;

        	Application app = new Application();
	        app.Run(wnd);
	}
}


これまたさっそくコンパイルして実行してみます。



テストという文字が表示されており、その下にボタンが2つ表示されています。
まずは上のボタンを押してみます。



テストという文字が中央揃えから左寄せになりました。
もう一度同じボタンを押してみます。




文字が右寄せに変更されました。
さらにもう一度ボタンを押してみます。



うーん...。
これは左寄せとの違いがちょっと分かりにくいです。とりあえず両端揃えとするとこんな感じになるようです。
最後にもう一度同じボタンを押してみます。



これで最初の状態に戻りました。
次に一番下のボタンを押してみます。



なにやら「テスト」という文字がさまざまなスタイルで追加されました。
TextBlockを使うと、表示する文字の場所(レイアウト)やスタイルを変えるのも簡単に実施できます。


それにしても4章長いなあ。
techedBOFで聴いた限りでは、xamlの直接記述とデータバインドがWPFの肝らしいのですが、どちらもまったく手をつけていません。
次回から少し飛ばしながらやっていこうと思います。