僕がやったxaml戦略
TRANSCRIPT
自己紹介
森 博之(もり ひろゆき)
MS開発技術を専門としたフリーランスエンジニア
Microsoft MVP for Visual C#
極東IT-Engineers 代表
ブログ:もり ひろゆきの日々是勉強
http://moriblog.kit-eng.com
Windows8対応[基本+実用]
Windowsストアアプリ開発入門 好評発売中!
私とXAML
XAMLとの出会い
WPF/E(Windows Presentation Foundation / Everywhere)
現在→WPF/Windows Phone(Silverlight)/Windowsストアアプリ
XAMLの説明を読んだ第一印象
XMLかぁ・・・設定ファイルみたいなのはやだなぁ・・・。
宣言型マークアップ言語
そんなに浸透するのかなぁ?
アプリを作成するためにXMLとC#を行き来して・・・
結局多くのアプリ開発はデザイナーとコードを行き来する
XAMLとは
eXtensible Application Markup Language
XMLベースの宣言型マークアップ言語
→XMLの規約が適用されている
必要がない場合は変数宣言を行わなくともよい
オブジェクトのインスタンス化スクリプト
<Button Content=“Click” />
[C#]var btn = new Button() { Content = “Click” };
[VB]Dim btn = New Button With { .Content = “Click” }
XMLの規約を踏襲しているので・・・
利用されている文字コードはUTF-8
XML Namespaceによってアセンブリをマッピング!
WPF/Windows Phone(Silverlight)/Windowsストアアプリで方言がある!
URI形式:xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WinStoreApp:xmlns:local="using:_01_WindowsStoreAppXaml"
WPF: xmlns:usercontrol="clr-namespace:Wpf.Lib;assembly=WpfControlLibrary1"
WP(SL):xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
コンテンツプロパティ属性
コンテンツプロパティ属性
クラスにContentProperty属性を付与
XAMLでプロパティ指定のないコンテンツの格納先プロパティを定義
[ContentProperty("Title")]
public class SampleButton : Button
{
public string Title { get; set; }}
コレクション構文
.NETでリストなどのコレクションに要素を追加するような場合
AddメソッドやAddRangeなどを利用する。
コレクション初期化子などを利用する。
XAMLではIListインターフェースを継承する(つまり、Addメソッドを持つ)オブジェクトにはコンテンツ領域に複数のオブジェクトを指定できる
<StackPanel><Button FontSize="40">ボタン1</Button>
<Button FontSize="40">ボタン2</Button>
<Button FontSize="40">ボタン3</Button>
</StackPanel>
パネル
UI要素は1つで完結することはあまりない!
複数のUI要素を利用する場合、どのように配置するかを指定する必要がある
XAMLでレイアウトを指定→パネルコントロール!
Panelの数はWPFがダントツ!
Windows Store WPF Windows Phone(Silverlight)
Grid Grid Grid
StackPanel StackPanel StackPanel
Canvas Canvas Canvas
DockPanel
WrapPanel
UniformGrid
XAML系フレームワークにおけるデータバインディングとは
データバインディングとは
2つのデータポイントの同期を保つための技術
エッセンシャルWPFより
同期=常に同じ値となるように保つ
⇒主にFrameworkElementクラスとBindingクラスで実現
基本的なBindingのイメージ
BindingTarget (バインディングターゲット)
FrameworkElementの派生クラス
BindingSource (バインディングソース)
任意オブジェクト
BindingTarget BindingSourceBinding
依存関係プロパティ
プロパティ値の変化を検知・通知するためのアプリケーション内のインフラ
DependencyObjectクラス・DependencyPropertyクラスによって実現
つまり、言語仕様ではなくクラスライブラリにより実現されている
実装例で確認してみよう
依存関係プロパティの実装例
public class MyText : DependencyObject{
public static readonly DependencyProeprty TextProperty =DependencyProperty.Register(“Text”, typeof(string),
typeof(MyText));public string Text{
get { return (string) this.GetValue(TextProperty); }set { this.SetValue(TextProperty, value); }
}}
<MyText Text=“テキスト” />
値の通知方式
UIデータ変化の通知を必要とするXAML系の機能
アニメーション
データバインディング
これらの通知にはイベントの仕組みが用いられている
INotifyPropertyChanged
INotifyCollectionChanged
プロパティ変化の通知
INotifyPropertyChanged
public class Person : INotifyPropertyChanged {public event PropertyChangedEventHandler PropertyChanged;
private string name;public string PersonName {
get { return name; } set {
name = value;OnPropertyChanged("PersonName");
}}
protected void OnPropertyChanged(string propertyName) {if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
}
}
基本的なBindingのイメージ
BindingTarget (バインディングターゲット)
FrameworkElementの派生クラス
上記オブジェクトの依存関係プロパティ
BindingSource (バインディングソース)
任意オブジェクト
BindingTarget BindingSourceBinding
マークアップ拡張
属性構文で一部のオブジェクトを指定できるようにするための仕組み
<TextBlock><TextBlock.Text>
<Binding ElementName=“MyTextBox” Path=“Text” /></TextBlock.Text>
</TextBlock>
<TextBlock Text=“{Binding ElementName=MyTextBox,Path=Text}” />
マークアップ拡張の作成
<TextBlock Text=“{demo:Hello}” />
using System;using System.Windows.Markup;
namespace BindingDemo{
public class HelloExtension : MarkupExtension{
public override object ProvideValue(IServiceProvider serviceProvider){
return "Hello";}
}}
今回は仕組みを理解してもらうために作成方法を説明しましたが、マークアップ拡張の自作は可読性を落とす原因となりえるため注意が必要です。
だいたいの場合、データバインディングで解決できるはずですので、まずはデータバインディングで解決できないか検討しましょう。
XAMLで言うアニメーション
タイムスライスによるアニメーション
UIに紐づくプロパティ値を時系列に値変化を与えることで実現している。
つまり、UI要素のどのプロパティにどのような値を適用するのかということがXAML系アニメーションでは重要となる
XAML系アニメーション
タイムスライスによるアニメーション
プロパティ値を時系列で変化させることで実現している
具体的には・・・
プロパティ値を変化させる
⇒Animationクラス
Animationの開始するきっかけの指定
⇒コード、トリガー、VisualStateManager
Animationクラス
Animationクラスではプロパティに設定する設定値を発生させる
⇒最終的には対象となるプロパティに設定する値となる訳だから対象プロパティに併せてAnimationオブジェクトを選択する
Double⇒ DoubleAnimation
Color ⇒ ColorAnimation
Point ⇒ PointAnimation
(WPFの場合はこの他にも豊富なAnimationクラスが用意されている)
Animationクラスのプロパティ
System.Windows.Media.Animation名前空間
プロパティ 意味、役割
From 開始値
To 終了値
By From値またはプロパティの設定値に指定値を加算し終了値にする
BeginTime,Duration 開始時間、アニメーション時間
RepeatBehavior リピート回数
Animation対象の設定
Storyboardを利用
Storyboard
直訳すると絵コンテ
XAML系ではAnimationオブジェクトを複数内包するChildrenプロパティを持つ
Animationの値設定はStoryboardへ添付プロパティで行う
<Storyboard><DoubleAnimation
Storyboard.TargetName="MyTextBox" Storyboard.TargetProperty=“FontSize”
From="1.0" To="0.0" Duration="0:0:1" /></Storyboard>
参考)~AnimationUsingKeyFrame
時系列でアニメーションの値変化を制御したい場合などに利用できる
DurationやBegin/Endの代わりにKeyFrameオブジェクトを指定する
<ColorAnimationUsingKeyFrames.KeyFrames><LinearColorKeyFrame KeyTime="0:0:0.25" Value="Red" /><LinearColorKeyFrame KeyTime="0:0:0.5" Value="Blue" /><LinearColorKeyFrame KeyTime="0:0:0.75" Value="Yellow" /><LinearColorKeyFrame KeyTime="0:0:1" Value="Green" />
</ColorAnimationUsingKeyFrames.KeyFrames>
実際のレイアウトには・・・
PanelコントロールにはUI要素のコレクションを保持し、内包するUI要素のレイアウトを管理するという機能を持つ
実際のレイアウトの配置には「スロットモデル」と呼ばれる仕組みが用いられている
UI要素の階層内で測定・配置の2段階でサイズ調整を行う
UI要素内でレイアウトに連動するプロパティの変化を検知すると変化した値に応じてレイアウト調整が動作する
1.Measure
2.Arrange
1.Measure
2.ArrangeResize!
Grid
StackPanel
TextBlock
TextBox
Button
TextBlock
参考)Windowsストアアプリでは・・・。
Windowsストアアプリで利用できるアニメーションの追加機能
アニメーション実装済コントロール
あらかじめコントロールにアニメーションが組み込まれている。
切り替え効果
コントロールの子要素の追加・削除などコントロールの挙動に合わせたアニメーション定義を行う仕組み
テーマアニメーション
切替効果より詳細な定義が可能。
一般的によく利用されるようなアニメーションが定義されている。
Model-View-ViewModel
XAML系フレームワークを利用しているとMVVMというキーワードを耳にするようになる。
そういえば本日のセッションにも・・・・
少し大きなアプリケーションをプログラミングするとやはりプログラムの依存性の高さによってコードの保守性を損ねたりする。
高凝縮
疎結合
→独立性の高いシンプルなモジュールで構成するほうが可読性が高くなる
n層のアプリを作成することもこういった問題へのアプローチの1つ。
Model-View-Controller
WebやClientでメジャーな分離パターン
本質的にはモデルとなるビジネスロジックからプレゼンテーションを分離を行うことで関心事の分離を行うパターン
XAML系のフレームワークでは外観をXAMLで作成することができる
→コントロールへの値の適用はバインディングにより実現が可能
→それ以外にもビヘイビアやトリガー、コマンドなどを利用することでコードビハインドにあるコードもバインディングオブジェクトに格納することが可能となる
→ViewModel
MVVMを取り入れるには
基本的にはデータバインディングをベースにしたパターン
インフラなしではやはり少し厳しい・・・。
著名なフレームワーク
Livet
公開場所: http://ugaya40.net/livet
WPF用フレームワーク
MVVM Light Toolkit
公開場所: https://mvvmlight.codeplex.com/
Windowsストアアプリ/WPF/SilverlightなどXAML系フレームワークで利用できる
まとめ
XAMLによる表現力の向上は無視できない!
習得のハードルはそれほど高くない!
情報はかなりそろってきている
データバインディング|アニメーション
紹介しきれなかった有用な機能がまだまだあります!
難しいようですが、こちらも情報は結構あります!
Blendなどを組み合わせるとより簡単に!
Model-View-ViewModel
XAMLでまともに開発するとなると、押さえる必要がある