Hatena::ブログ(Diary)

C#でプログラミングあれこれ このページをアンテナに追加 RSSフィード

2014-04-06

[][][]WPFらしいアプリケーションの例 1周遅れのWPF入門

マイクロソフトプラットフォームでWinFormsからWPFに移行せなアカンなーとかWPFにしたら何が嬉しいの?なんてことを思ってる人たちに捧げるシリーズです。

今回はWPFで作ったら何が嬉しいのかを俺っち的に感じられる例を1つあげてみる。

Visual Studio 2013(VS2012でも変わらんと思う)
.NET Framework 4.0(企業戦士のデフォルトWindows7な筈なので)

で仕上げていきます。まずはプロジェクトの作成から
f:id:fkmt5:20140407012108p:image
で、スケルトンの出来上がり。

MainWindow.xamlが選択されてるはずなので、左側にツールボックスとドキュメントアウトラインを表示させます。
f:id:fkmt5:20140407012109p:image
今回は理屈抜きで手順を並べていきます。習うより慣れよ。理解は後からついてくる。
ツールボックス上でコンボボックスをダブルクリックします。
f:id:fkmt5:20140407012700p:image
そしたらウィンドウの左上にコンボボックスが配置されます。
f:id:fkmt5:20140407012701p:image
左上すぎるんで、マウスでグリグリとマージンをとりましょう。(位置合わせ)
f:id:fkmt5:20140407012702p:image
その時、Xamlのコードは↓こんな感じになってるはずです。

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>

    </Grid>
</Window>

同様にLabelを1つと
f:id:fkmt5:20140407013426p:image
TextBoxを1つダブルクリックで配置します。
f:id:fkmt5:20140407013425p:image
同じようにマウスでグリグリっと位置合わせして
f:id:fkmt5:20140407013424p:image
こんな感じになる。
f:id:fkmt5:20140407013423p:image
その時、Xamlのコードは↓こんな感じになってるはずです。

    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>
        <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,52,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,56,0,0"/>

    </Grid>

同じ要領でLabelを3つ、TextBoxも3つにします。
f:id:fkmt5:20140407013930p:image
f:id:fkmt5:20140407013929p:image
その時、Xamlのコード↓

    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>
        <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,52,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,56,0,0"/>
        <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,95,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,99,0,0"/>
        <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,137,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,141,0,0"/>

    </Grid>

で、LabelのラベルがLabelじゃ味気ないんで企業戦士らしいラベルに変えます。雰囲気が出るようにね。
上から、ID、名前、住所でどうでしょうか。
ウィンドウ上でLabelにカーソルを入れる(≒ゆっくりクリックする)とラベルの編集に入ります。
f:id:fkmt5:20140407014413p:image
f:id:fkmt5:20140407014414p:image
これはLabelタグのContent属性を書き換えるのと同じです。

    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>
        <Label Content="ID" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,52,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,56,0,0"/>
        <Label Content="名前" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,95,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,99,0,0"/>
        <Label Content="住所" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,137,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,141,0,0"/>

    </Grid>

デザイン上での操作はいったん止めてC#のコードに向き合います。
ソリューションエクスプローラ(右側)のプロジェクトの上で右クリックして
f:id:fkmt5:20140407015512p:image
Memberクラスを作ります。
f:id:fkmt5:20140407015513p:image
出来たてはこんな感じ。
Member.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WpfApplication2
{
    class Member
    {
    }
}

で、C#の良い感じのシンタックスを使ってプロパティを3つ作ります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WpfApplication2
{
    class Member
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }
}

続いて、MainWindow.xaml.csを開きます。(MainWindow.xamlの画面でF7キーが早いかな?)
初期コードは↓こんな感じ
MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

サンプルデータを1つ作ります。

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

            var member = new Member
            {
                Id = "1000",
                Name = "fuku518",
                Address = "大阪府"
            };
            this.DataContext = member;
        }
    }

ここで実行して、なんとなく期待通りの表示になったら超嬉しいけどもうちょっとだけやることがあります。
MainWindow.xamlに表示を切り替えてxamlと少しだけ向き合います。(Shift+F7で切り替わる)
TextBoxの定義は

<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Margin="69,56,0,0"/>

こんな感じになってると思うので、その中のText属性をそれぞれ
"TextBox"から"{Binding Id}"、"{Binding Name}"、"{Binding Address}"
結果↓こんな感じになります。

    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>
        <Label Content="ID" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,52,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Id}" VerticalAlignment="Top" Width="120" Margin="69,56,0,0"/>
        <Label Content="名前" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,95,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top" Width="120" Margin="69,99,0,0"/>
        <Label Content="住所" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,137,0,0"/>
        <TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Address}" VerticalAlignment="Top" Width="120" Margin="69,141,0,0"/>

    </Grid>

では実行してみましょう。
f:id:fkmt5:20140407021011p:image
ま、普通ですね。

アプリケーション内部に持つデータを画面表示に使う部品(ウィンドウズで言えばコントロール)に値を設定することで表示するのでは無く、データの項目名(プロパティ名)とコントロールの表示内容を結び付けて(Bind)同期させる。
これがWPFを使う1番最初の動機たりえるメリット。内部データモデルとビューの同期。(ただし、一方通行)

全部書くから超長い。だけど、こういう情報が本当に必要な人にはそれぐらいわかるやん!って省略したところでハマったりしがちなんで可能な限り端から端まで記述してく。

長すぎるんで、今日はここまで。次はメンバー一覧の表示をします。

三行三行 2014/04/07 20:59 社内の仕事はEXCEL VBA+ADOであらかた済ませてましたが
最近C#に興味を持って、WPFの情報を探してたところここにたどり着きました
とても参考になります。がんばってください

fkmt5fkmt5 2014/04/12 13:01 コメントありがとうございます!ちょっと嬉しいですね。ぼちぼち行きます。

C#初心者C#初心者 2014/04/29 19:41 >こういう情報が本当に必要な人にはそれぐらいわかるやん!って
>省略したところでハマったりしがち

まさに↑状態で「WPFにしたら何が嬉しいの?」とハマってました^^;
わかりやすい解説で大変参考になりました
今後の記事も楽しみにしています

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/fkmt5/20140406/1396804749
リンク元