ふらっと覗いたら出てました。
http://karlshifflett.wordpress.com/xaml-power-toys/
上記ページのDownloadsという項目のところにインストーラをダウンロードするためのリンクがはられています。
setup.exeをダブルクリックして、ひたすらYesマンになればインストールは完了です。
v4までは、インストール後にオプションのアドイン/マクロ セキュリティにXAML Power Toysのインストールフォルダを追加する必要がありましたが、今回からは必要ないみたいです。
既に追加してる人はさくっと消してしまいましょう。
上記のスクリーンショットで選択している項目がある場合は消す。
軽く使ってみる
ちょっと軽く使って見ます。
「ToysHelloWorld」という名前でWPF アプリケーションを作成します。
Modelsフォルダを作成して、いつも作ってるPersonクラスを、さくっと作ります。
using System;
namespace ToysHelloWorld.Models
{
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime Birthday { get; set; }
}
}
続けて、XAML Power Toysを使うための下準備をします。
XAML Power Toysは、void OnPropertyChanged(string name)という名前のメソッドを持つViewModelBaseというクラスと、RelayCommandというクラスを準備していると、使い勝手がいいように作られています。
まず、ViewModelBaseをさくっと作成します。ViewModelsというフォルダを作成してそこに以下のコードを作成します。
using System.ComponentModel;
namespace ToysHelloWorld.ViewModels
{
public class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged メンバ
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var h = PropertyChanged;
if (h != null)
{
h(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
}
RelayCommandは、XAML Power Toysのインストーラと一緒に入っているので、それをこぴぺして使います。
ここでは、Commandsというフォルダを作成して、そこにコピペして、namespaceをToysHelloWorld.Commandsに変更しました。
Viewの作成
Viewとして、ユーザコントロールを1つ作成します。
Viewsというフォルダを作成して、PersonViewという名前でユーザコントロールを作成しました。
<UserControl x:Class="ToysHelloWorld.Views.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock Text="PersonView" />
</Grid>
</UserControl>
とりあえず、表示されればいいので、中身は適当にTextBlockを1つ置いておきます。
ViewModelの作成
続いてViewModelを作っていきます。
ViewModelsフォルダにPersonViewModelという名前のクラスを作成して、ViewModelBaseを継承させます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ToysHelloWorld.ViewModels
{
public class PersonViewModel : ViewModelBase
{
}
}
ここで一回ビルドして、XAML Power Toysが、アセンブリを認識できるようにしておきます。(超重要)
この10行目あたりにカーソルを持っていって、右クリックメニューからXAML Power Toys → Create ViewModel For Classを選択します。
そして、先ほど作ったPersonクラスを選択します。
Nextを押すと、下のような画面が出てきます。
ここで、プロパティをReadOnlyにするかとか細かく色々設定したり、下のように、プロパティの型を単一の要素から、Listにすることもできます。
さらに、Step2のタブに行くと、ViewModelの元になるModelクラス(今回の例ではPersonクラス)のプロパティをラップするような形のプロパティを定義するかを指定できます。
さらに、AddCommandボタンを押すと、ViewModelに追加するコマンドも作成できます。
ここでは、Selectという名前のコマンドを、CanExecute無しの状態で作っています。
Createボタンを押すことで、コマンドが追加されます。
最後に、Create ViewModelの画面で、Createボタンを押すと、クリップボードに今作ったViewModelのコードが追加されます。コードを貼り付けると、以下のような感じになります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ToysHelloWorld.ViewModels
{
public class PersonViewModel : ViewModelBase
{
//TODO developers please add your constructors in the below constructor region.
// be sure to include an overloaded constructor that takes a model type.
#region Declarations
private ICommand _selectCommand;
private Person _person;
#endregion
#region Properties
public Person Person
{
get { return _person; }
set
{
_person = value;
OnPropertyChanged("Person");
}
}
public DateTime Birthday
{
get { return _person.Birthday; }
set
{
_person.Birthday = value;
OnPropertyChanged("Birthday");
}
}
public Int32 ID
{
get { return _person.ID; }
set
{
_person.ID = value;
OnPropertyChanged("ID");
}
}
public String Name
{
get { return _person.Name; }
set
{
_person.Name = value;
OnPropertyChanged("Name");
}
}
#endregion
#region Command Properties
public ICommand SelectCommand
{
get
{
if (_selectCommand == null)
{
_selectCommand = new RelayCommand(SelectExecute);
}
return _selectCommand;
}
}
#endregion
#region Constructors
//TODO developers add your constructors here
#endregion
#region Command Methods
private void SelectExecute(object param)
{
}
#endregion
}
}
usingがいくつか足りないと怒られるので、さくっと足しておきます。Constructorsのところにある、TODOコメントを消して、以下のようなコンストラクタをさくっと書いておきます。
#region Constructors
public PersonViewModel(Person person)
{
this.Person = person;
}
#endregion
最後に、Selectコマンドの処理を書いていきます。
ここでは、コマンドが走ったことがわかればいいので、Messageプロパティを新設して、そこに適当な文字列を突っ込むようにしました。
ここら辺は、OnPropertyChangedを呼ぶようなコードスニペットを準備しておくと楽チンです。(過去に紹介したタイプセーフなやり方でもOKです。)
#region Command Methods
private void SelectExecute(object param)
{
this.Message = string.Format(
"{0}: {1}, {2:yyyy/MM/dd}",
this.Person.ID,
this.Person.Name,
this.Person.Birthday);
}
#endregion
#region "追加したプロパティ"
private string _message;
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged("Message");
}
}
#endregion
ここまで出来たら、ビルドしてコンパイルエラーが出ないことを確認します。(重要!)
Viewの作成 その2
ViewModelが出来たので、先ほど、どんがらだけを作ったViewの作成の続きをやります。
PersonViewを開いて、Gridタグとかを消して、UserControlだけにします。
その状態で、右クリックメニューからXAML Power Toys→Create Form, ListView or DataGrid From Selected Classを選択します。
出てきた画面から、先ほど作成したPersonViewModelを選択します。
出てきた画面の左側にあるプロパティをドラッグアンドドロップで、画面右側にもっていきます。
各種設定を上記画面のようにして、 Createボタンを押すと、クリップボードにXAMLがコピーされるので、PersonViewに貼り付けます。
<UserControl x:Class="ToysHelloWorld.Views.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border BorderBrush="LightGray" BorderThickness="1" CornerRadius="10" Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Text="人間様編集フォーム" />
<Label Grid.Column="0" Grid.Row="1" Content="ID" />
<Label Grid.Column="0" Grid.Row="2" Content="Name" />
<Label Grid.Column="0" Grid.Row="3" Content="Birthday" />
<Label Grid.Column="0" Grid.Row="4" Content="Message" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Path=ID}" />
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Width="250" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Path=Birthday, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat=\{0:yyyy/MM/dd\}}" Width="250" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBlock Grid.Column="1" Grid.Row="4" Text="{Binding Path=Message}" />
<Grid Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="2" Grid.IsSharedSizeScope="True" HorizontalAlignment="Right">
<!-- ここら辺を書き換えて Selectコマンドとボタンの紐付けやってます -->
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Buttons" />
</Grid.ColumnDefinitions>
<Button Content="Select" Padding="3.5,0,3.5,0" Margin="3" Command="{Binding SelectCommand}"/>
</Grid>
</Grid>
</Border>
</UserControl>
これで、Viewは出来上がりです。
仕上げ(紐付け)
最後に、ViewModelとViewの紐付けを行います。
App.xamlにDataTemplateを追加して、PersonViewModelとPersonViewを対応付けます。
<Application x:Class="ToysHelloWorld.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:ToysHelloWorld.ViewModels"
xmlns:views="clr-namespace:ToysHelloWorld.Views"
StartupUri="Window1.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type viewModels:PersonViewModel}">
<views:PersonView />
</DataTemplate>
</Application.Resources>
</Application>
そして、今まで影の薄かったWindow1のコンストラクタで、ContentにPersonViewModelを設定します。
using System;
using System.Windows;
using ToysHelloWorld.Models;
using ToysHelloWorld.ViewModels;
namespace ToysHelloWorld
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Content = new PersonViewModel(
new Person
{
ID = 10000,
Name = "田中 麻呂",
Birthday = DateTime.ParseExact("1981/01/30", "yyyy/MM/dd", null)
});
}
}
}
実行してみよう
実行してみると、以下のような画面が表示されます。
適当に値を書き換えて、Selectボタンを押すと、ちゃんと動いてることがわかります。
簡単にまとめ
ということで、XAML Power Toysを超簡単に使ってみました。
使った機能以外にも、DataGridやListViewに対応したXAMLを出力したりと、使いでのある感じです。
ただ、ちょっと修正が入ると、コードの再生成しなおしっぽいので、そこらへんちょっと大変そうな気がしました。
とりあえずひながたコードをXAML Power Toysでつくって、それをベースに作りこんでいくのがいいのかもしれないです。