26. Case 1: User Control
•完成!… と、思うじゃろ?
−そのときしか使わない場合は、それで完成。
−他のプロジェクトでも使い回したい場合は…? そして、他のプロジェクトでは外観を変更したい場合は…?
次のアプリでも使うよ
ただしボタンをデカくしてくれ
大変申し訳ございません早急に 影響調査し対応致しますので今 暫くお待ち頂きますよう宜しk
27. Feature of User Control
•UserControl型からの派生
−アプリケーション構築と同じ方法で作れる
▫Window / Page を作成するのと同じ要領で、ポトペタ開発
▫既存のコンポーネントだけで構成されている
−複雑なカスタマイズをサポートしない Background やBorderBrushを外部から指定する、程度の簡単なカスタマイズはでちる しかし、DataTemplateやControlTemplateによる外部からのカスタマイズはできない
31. Feature of Custom Control
•Control 型からの派生
−ロジックと外観の完全な分離
▫コントロールの振る舞いを、ロジック(.cs) に
▫コントロールの外観を、Style/Template(Generic.xaml) に
−.NET Framework が提供するコントロールと同じ実装
−コントロールの外観をカスタマイズ可能 ControlTemplateにより、あらゆる外観に設定可能
32. Parts and States Model
•視覚的な構造と動作はControlTemplateで定義
−外観を直接ロジックで書くのはダメゼッタイ
−NumericUpDownの場合
負の値のときは
文字を赤くしたい…
TextBoxのForeground を
SolidColorBrushのRed に…
33. Parts and States Model
•視覚的な構造と動作はControlTemplateで定義
−外観を直接ロジックで書くのはダメゼッタイ
−NumericUpDownの場合
負の値のときは
文字を赤くしたい…
TextBoxのForeground を
SolidColorBrushのRed に…
ValueStates
•Positive
•Negative
正負をVisualStateで保持
負の値でどうなるか、は
ControlTemplateで自由に実装
34. Parts and States Model
•ControlTemplateとロジックの接点
−コントロールの要件(命題) を満たすうえで必要なパーツ
−NumericUpDownの場合
▫Click イベントを購読するため、ロジックから参照しなければならない
Value を増減させるためのButton が必ず必要
名前付きパーツとOnApplyTemplateメソッド
35. Parts and States Model
•名前付きパーツ
−例えば、System.Windows.Controls.ComboBoxの場合 http://msdn.microsoft.com/ja-jp/library/ms752094.aspx
36. Parts and States Model
•名前付きパーツ
−例えば、System.Windows.Controls.ComboBoxの場合 http://msdn.microsoft.com/ja-jp/library/ms752094.aspx
<Gridx:Name="templateRoot"
SnapsToDevicePixels="true">
<!--中略-->
<Popupx:Name="PART_Popup"
AllowsTransparency="true"
Grid.ColumnSpan="2"
IsOpen="{BindingIsDropDownOpen,RelativeSource={RelativeSourceTemplatedParent}}"
PopupAnimation="{DynamicResource{x:StaticSystemParameters.ComboBoxPopupAnimationKey}}"
Placement="Bottom">
<!--中略-->
<Borderx:Name="border"
Background="{StaticResourceTextBox.Static.Background}"
Margin="{TemplateBindingBorderThickness}">
<TextBoxx:Name="PART_EditableTextBox"
HorizontalContentAlignment="{TemplateBindingHorizontalContentAlignment}"
IsReadOnly="{BindingIsReadOnly,RelativeSource={RelativeSourceTemplatedParent}}"
Margin="{TemplateBindingPadding}"
Style="{StaticResourceComboBoxEditableTextBox}"
VerticalContentAlignment="{TemplateBindingVerticalContentAlignment}" />
</Border>
</Grid>
ComboBoxのControlTemplate(default)
37. Parts and States Model
•OnApplyTemplateメソッド
−ControlTemplateのVisual Tree が構築されたとき実行される ロジックからControlTemplateの実装にアクセスできる最も早いタイミング
•GetTemplateChildメソッド
−ControlTemplate内の名前付き要素を返す ControlTemplate内にある名前付きパーツのインスタンスを取得できる!
38. Parts and States Model
•コントロールコントラクト
−ロジックが使用する視覚的要素 名前付きパーツ
−視覚的に作用するpublic PropertyNumericUpDownでいうValue プロパティなど
−コントロールの状態とグループ VisualStates/ VisualStatesGroup
39. Parts and States Model
•コントロールコントラクト
−ロジックが使用する視覚的要素 名前付きパーツ
−視覚的に作用するpublic PropertyNumericUpDownでいうValue プロパティなど
−コントロールの状態とグループ VisualStates/ VisualStatesGroup
[TemplatePart(Name = "PART_UpButton", Type = typeof(Button))]
[TemplatePart(Name = "PART_DownButton", Type = typeof(Button))]
publicclassCustomControl1: Control
{
privateButtonupButton;
privateButtondownButton;
publicoverridevoidOnApplyTemplate()
{
base.OnApplyTemplate();
this.upButton= this.GetTemplateChild("PART_UpButton") asButton;
if(this.upButton!= null)
{
this.upButton.Click+= (sender, e) => this.Value++;
}
// 以下略
45. Without creating a new control
•新しいコントロールを自作しないための方法 作らないで済むならそれに越したことはなく。
CircleButton、とか作りたくなってくるが…
マウスオーバーと
クリック時に
全体の色を変える…
円と矢印、
押しやすいように
Margin 広めで…
Dark テーマに
対応…
46. Without creating a new control
•新しいコントロールを自作しないための方法 作らないで済むならそれに越したことはなく。
CircleButton、とか作りたくなってくるが…
マウスオーバーと
クリック時に
全体の色を変える…
円と矢印、
押しやすいように
Margin 広めで…
<Button>
<Grid>
<Ellipse/>
<PathData=""/>
</Grid>
</Button>
Button + リッチコンテンツ+ Style で実現可能 カスタムコントロールを作る必要は、ない
Dark テーマに
対応…
47. Find the best possible choice
•コントロールの価値命題
−こそが重要
−外観ではなく、コントロールの原理/ 振る舞い XAML Platform では、外観はいくらでも作り込めるので、一切関係ない
TabControl
ListBox
ItemsControl
見た目は同じでも、要件が異なるので、それぞれ違うコントロールをベースにしている