泥庭

2013年12月21日

WPFだからできること

Filed under: .NET, WPF — タグ: , , , — yone64 @ 6:58 PM

この記事は、XAML Advent Calendarの第21日目の記事です。

WPFは、XAMLでUIを定義するプラットフォームの始祖にしてもっとも強力な機構を持っています。
そこで、他プラットフォームでは使えないWPFならではの記述を2つ紹介します。

  1. SetterでBindingを設定
  2. DataTemplateでDataTypeを指定

サンプルコードはこちら

<Window x:Class="WpfSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfSample.ViewModels"
        Title="MainWindow" Height="200" Width="250">
    <Grid>
        <ItemsControl ItemsSource="{Binding}">
            <ItemsControl.Resources>
                <DataTemplate DataType="{x:Type vm:ButtonViewModel}">
                    <Button Content="{Binding Text}" Command="{Binding Command}"></Button>
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:TextBoxViewModel}">
                    <TextBox Text="{Binding Text}"/>
                </DataTemplate>
            </ItemsControl.Resources>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas></Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Left" Value="{Binding Left}"/>
                    <Setter Property="Canvas.Top" Value="{Binding Top}"/>
                    <Setter Property="Canvas.Width" Value="{Binding Width}"/>
                    <Setter Property="Canvas.Height" Value="{Binding Height}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
    </Grid>
</Window>
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;
using WpfSample.ViewModels;

namespace WpfSample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var text = new TextBoxViewModel { Left = 10, Top = 10, Width = 200, Height = 20, Text = "Hello" };
            var button = new ButtonViewModel 
            {
                Left = 90,
                Top = 120,
                Width = 100,
                Height = 20, 
                Text = "Click",
                Command = new RelayCommand(new Action(()=> MessageBox.Show(text.Text))),
            };

            this.DataContext = new List<ViewModelBase> { text, button};
        }
    }
}

実行結果はこちら。

キャプチャ3

まずひとつ目から、
ItemsControl.ItemsContainerSytleで定義しているように、StyleのSetterのValueにBindingを指定することができます。
これにより、ContentControlの各プロパティーとViewModelのプロパティーのBindingが可能になります。これはなかなか便利なのでおすすめ。
よく使うのは、上の例のように、ItemPanel上での位置情報をBindingで指定したり、あとはListBoxのIsSelectedをViewModel側で参照したいときとかでしょうか。

ふたつ目は、DataTemplateのDataTypeプロパティー。
このプロパティーを利用すると、ViewModelの型で適用するStyleを切り替えることができます。上の例では、TextBoxとButtonのコントロールをViewModelの型で指定しています。
動的に画面の構成が変わる画面を作成する場合は、ひとつ目のBindingの仕組みと組み合わせると便利です。

以上、他のXAMLプラットフォームからWPFに来た方は参考にしてみてください。

※ItemsControlのBinding周りは、XAML Advent Calendar 1日目のぐらばくさんのエントリーが非常にくわしいです。

なお、ソースコードの全体は、githubに上げてあります。

1件のコメント »

  1. […] 前日はyone64さんの「WPFだからできること」でした。 […]

    ピンバック by 動的にXAMLを表示する。 | もりひろゆきの日々是勉強 — 2013年12月23日 @ 12:10 AM


RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com で無料サイトやブログを作成.

%d人のブロガーが「いいね」をつけました。