ブログ「サイバー少年」

ブログ「サイバー少年」へようこそ!
小学六年生ごろからプログラミングを趣味にしている高校生のブログです。
勉強したことについての記事などを書いています。フリーソフトも制作、公開しています。
(当ブログについて詳しくは「ブログ概要紹介」を参照)

サイバー少年が作ったフリーソフトは「サイバー少年の作品展示場」へ

XAMLのTriggerの勉強 ~ そしてLoose XAMLへ ~

先月ぐらいからXAMLのTriggerにハマっていたり、ハマっていなかったりします。

Triggerすごいですね。XAMLだけでできるとは。

しかし、Triggerなんて使わなくても、プログラムコードでだいたい同じことは出来るわけです。

プログラムコードで書けばいいじゃんと思ったりしてしまいますが、違うのです。

Triggerは、“プログラムコードでやるはずのものをXAMLで書けるようにする”ための物なのです。


いわゆる“デザインとロジックの分離”のための物ですね。


たとえば、押したときに赤く光るボタンを作りたいとなったときに、

C#等のコードでMouseDownとMouseUpの処理を書くという発想をしがちですが、

それが1つぐらいならいいでしょうけど、
色んな光り方のパターンがあって、全部作るとなると、訳がわからないコードになります。

(もちろん、UIのクラスを上手にカプセル化できる人もいますから、必ずしも訳がわからなくなるとは限りません。)

そこで、ボタンなどのUIの装飾はXAMLに書けるようにしたかったわけですね。

それで、Triggerがある、と。




しかし、Triggerのもう一つの便利さに気が付きました。

Loose XAMLとの相性が良いのです!



Loose XAMLというのは、普通のWPFアプリケーションが、

XAMLをBAML化→C#等で書いたアセンブリと結合→EXEファイル

となるのに対し、

XAML→実行エンジンに渡す→実行

というスクリプトのようなことができる技術です。


実行エンジンは、簡単にいえばWebブラウザのIEです。

IEでWPFのエンジンを呼んだりして、XAMLを解析してボタンなどが表示されます。


しかし、アセンブリとの結合がありませんから、C#等のコードを動かすことはできません。


ところで、Loose XAMLにC#やVB.NETのコードを埋め込んでスクリプティングできるようになったら最強ですよね~。

なんで作らないのだろうか。


本題に戻り、なぜTriggerとLoose XAMLの相性がいいのかというと、C#のコードなしでもUIの装飾ができるからです。

もし、Triggerが無かったとすると、先ほど述べたように、
押したときに赤く光るボタンを作るときに、C#等のコードが必要といなります。

(MouseDownとMouseUpのイベントハンドラを書く。もちろんその他の手段でもいけるはずですけども、なんにせよC#等のコードは必要です。)

しかし、Loose XAMLではC#等のコードは書けません。

Loose XAMLでUIの装飾ができないというのはアレですから、Triggerを使うのです。

そうです、Triggerがあるおかげで、Loose XAMLでもUIの装飾ができるのです。
Tirggerバンザイ!


と言っても、Loose XAMLの需要はあまり無いんですけどね…。




TriggerがLoose XAMLのためにあるわけではないでしょうけど、

WPFはUIの装飾を99%、XAMLだけで書けるようになっていると思います。

ですから、Loose XAMLでもその恩恵を受けられて、Loose XAMLでもUIの装飾ができるわけです。


ちなみに、私がXAMLのTriggerに興味を持ちだしたキッカケはこのブログ記事です。

Animation and Trigger, Loose XAML - 川西 裕幸のブログ - Site Home - MSDN Blogs
http://blogs.msdn.com/b/hiroyuk/archive/2006/10/06/animation-and-trigger_2c00_-loose-xaml-.aspx

Loose XAMLだけで本格的な処理を行っています。
Triggerのおかげで成せる技ですね。

しかし、この人すごい…。




ところで、WPFにはデータバインディングというのもありますね。

これは、単純に、“どこかの値とどこかの値を同期させる”ためのものです。

チェックボックスのチェック状態で、ボタンの有効・無効を切り替えるといったようなものに使います。

これは、チェックボックスのイベントハンドラからボタンの有効無効を設定、というのが思いつきますが、XAMLだけでやりたかったわけです。


しかし、この例はUIの装飾とは関係ないので、先ほど述べたXAMLだけで書くことのメリットとは関係ありませんね。

実は、XAMLだけで書くことのメリットは、「UIの装飾がコードから外れてすっきりする」だけではありません。

MVVMパターン(デザインとロジックの分離)の実現です。


すみません。
私がMVVMパターンについては、まだよく理解していませんので、説明できそうにありません…。

しかし、データバインディングはMVVMパターンというものを実現しやすくするための、機能の一つというのは覚えておいてください。


つまり、データバインディングは、XAMLだけで2つの値を同期できるようにするため、

もっと言えば、MVVMパターンを実現しやすくするために生まれたものです。

実をいうと、TriggerもUIの装飾をXAMLに書けるというだけでなく、
MVVMパターンを実現しやすくする一面もあります。

Triggerは、データバインディングの高機能版とも言えるのです。

こっちのほうが、Triggerの主な使用目的…かも知れません。
詳しくは書きませんが。




おまけ (雑誌の付録といったところか!?)

Triggerと、その仲間であるMultiTriggerを使った、Loose XAMLとして動作するXAMLファイルを作ったので公開します。


「XAMLだけでこんなことができるのか」と、みなさんびっくりしますよ。

まぁ、びっくりなら、先ほど言った川西さんのブログのやつのほうが、びっくりしますけどね…。


あと、Loose XAMLはIEじゃないと動作しませんからご注意。

大多数の人ががっかりした様子が目に見えますが、仕方ないのです。

Google Chromeでも、WPFの実行エンジンを呼び出すプラグインとかあるのかな、と思ったら、無いんですよ…。


さて、まずはクリックしたら表示文字列が変わるボタンから。

厳密にはマウスボタンを押している間だけ表示文字列が変わります。

クリックしたら…というのは結構、難しいのです。

題して「じゃあ、いつやるか?


Hayashi.xaml - Yahoo!ボックス
http://yahoo.jp/box/psHv8t


どこかで聞いたことのあるセリフですが、まぁダウンロードしてくださいな(笑)


もう1つあります。こっちのほうがすごい。

題して、「未入力のとき色が変わって強調表示するテキストボックス

TextBox.xaml - Yahoo!ボックス
http://yahoo.jp/box/ub8lya

タイトルのままです。

未入力のときに灰色になります。
そして、未入力のときに、マウスカーソルを持ってきたら水色になります。

本当は、薄く「値を入力してください」と表示させたかったのですが、出来ないようなのです。

もちろん、C#のコードを入れると出来ますが…。
現在、XAMLだけで出来る方法を探しています。


以上の2つです。

XAMLだけで色んなことができるというのを、実感してみてください。




私は、TriggerとMultiTriggerしか知らない状態なのですが、
実を言うとTriggerには色んな種類があります。

DataTriggerとかEventTriggerとか…。

しかし、EventTriggerを調べてみましたが、一筋縄ではいきそうにないですね…。


さらに、Trigger関係ないですが、Storyboardというのもあります。

実は、川西さんのブログのやつも、Triggerのおかげだけでなく、Storyboardのおかげでもあります。

Storyboardも奥が深く、面白そうです。


WPFって…すごいですね。

tag:

コメント

バインディングについて少し触れていたので、コメントします。
ちょっと前にWPFを始めたわけですが、バインディングの理屈が難しい気がするんですよ…

XAMLにあるTextBoxコントロールのTextプロパティをString strにBindingしたとしますよね。
それをC#のコードで手を加えて、もっかいXAMLのTextBoxに返したい時に僕はDatacontextをnewしてるんですが、コントロールに名前をつけて直接Textプロパティにアクセスするのとどっちが楽なんでしょうか。。。
メモリの使用量は前者の方が4bit多いですが。。。

  • 2013/08/16(金) 08:17:54 |
  • URL |
  • AsaBon #-
  • [ 編集 ]

Re: AsaBon

あ、すみません、AsaBonさんのほうが詳しい気がします…(笑)
実は私は、ちょっとしか触ってないもので、まだUIとUI間でのバインディングしかやってないですね。
Datacontextも、「さあ勉強するぞ!」と言ったところで…。
お答えできません…。

といっても、まぁ、後者のほうがパフォーマンスはいい気がします。
前者は開発を楽にするためのものですので。

で、質問には答えられないので、関係ない話題を…。

4bitは4byteの言い間違いじゃないでしょうかね。メモリのアドレスのサイズですよね。
そのDatacontextとやらの参照のことを言っているのではないでしょうか。

Datacontextのインスタンスは4byteじゃないのです。
C言語で構造体をmallocした領域に入れるのと基本的には同じです。

構造体でdouble型とか、配列とか宣言すると、サイズは大きくなりますよね。
ですが、どれだけ大きくても、mallocから返ってきた値は4 or 8byteです。
この値はローカル変数ならばスタックに積まれますよね。
構造体が合計1024byteだったとすると、ヒープでは1024byte、スタックで4byte積まれ、合計1028byteです。

4byteというのはスタックに積まれた参照のことを言っていたのです。(知っていたらすいません。)

ちなみに、ローカル変数は関数を抜けると破棄されるので、すぐメモリから消えてしまいますね。
ですから、「メモリ消費」と名乗るものは、普通はヒープにあります。

ここまではすでにご存知だったかも知れません。


結局、クラスのインスタンスも構造体みたいなものです。
実装によるでしょうけど、非staticなフィールドがヒープに確保されます。

そして、クラスにはメソッドやstaticフィールドがあるわけですが、
メソッドやstaticなフィールドは一度作っておいて、各インスタンスで共通利用します。エコですね。


え~い、長くなってしまったから結論!
C#で
System.Object obj = new System.Object(); なんて書くと、
ヒープ領域にObjectのインスタンス(非staticフィールド、あとメタデータ、制御情報も?)が作られます。

変数objに入っているのは、そのインスタンスのアドレスのポイ…とはいきません。
あくまでもアドレスのポインタではなく、参照です(処理系による)。

内部的には、メモリアドレスと制御情報を含んでいるっぽいです。
ですから、参照を格納するサイズは、メモリのアドレスのサイズよりも大きいっぽいです。
参照とは、おまけ付きのポインタっぽいです。

ただ、私も詳しくないので数byteとしておきます。
つまり、ヒープには数byteを大いに超えているであろうデータが入っています。大体は。


Datacontextをインスタンス化させたときのメモリ消費量は、4byteではない!
とても大きいbyteなのです!

これで許してください…。

Webブラウザって常駐させたら起動が早くなるんじゃ?

こんにちは、はじめまして.
姉妹ブログの記事についてです.

かれこれ10年ほど前の話なので聞いたことないブラウザかもしれませんが,(非常にシェア率の高かった) Netscape Navigatorなどはタスクトレイに常駐してました.

2003年にこの様な質問があがっています.
>Netscape 7.1 の常時起動(タスクトレイに常駐)をやめるには?
>http://okwave.jp/qa/q625829.html

現在でもSleipnirあたりは常駐させているのではないでしょうか?

以降は個人的な想像と解釈なので信ぴょう性はありませんが一応.
・PCの性能(特にメモリ容量)が飛躍的に向上し,負荷低減のためにブラウザを終了したり,起動したりすることが減った.
・以前はブラウザの(今思えば)異常な多機能化が進んでいたが,今はシンプルになりサイズが小さくなった.
・一から起動したとしても昔のIDE(今はPATAと呼んだほうがいいかな?)と違い読み込みが高速である.
このあたりが,常駐化が廃れ,さらにあえて再現しない理由かと思います.

  • 2013/08/16(金) 22:53:41 |
  • URL |
  • かぼちゃ #S4pvVTuM
  • [ 編集 ]

Re: Webブラウザって常駐させたら起動が早くなるんじゃ?

あ、かぼちゃさんうちにも来ましたね。
div9851さんのブログ経由で、そちらのブログにも訪問、そしてコメントさせて頂きました。

Netscapeは存じております。
IEとの対立がすごかったようですね。
そんなIEも今じゃ…。頑張ってくれ!

Netscapeは常駐していたんですね~。

確かに、今は起動時間がものすごいかかるわけではないので、
常駐させる必要が無くなったというのは分ります。

それに、みんな常駐を嫌がりますしね。

でも私としては常駐させたいのですが、Sleipnirというのがあるんですよね。
一度、興味本位でインストールしたことがあるのですが、一回も起動していませんね(笑)
無名な感じがして使う気にならないと言ったら開発者たちが起こりそうですが。

いや~、そうなんですか。
ありがとうございます。

ブラウザ常駐は、今でもできますが。。。。?
Chrome
http://blogs.itmedia.co.jp/ten/2013/04/chrome-28d2.html
IE
http://www.forest.impress.co.jp/article/2006/02/16/okiniiri.html

WEBのつくり方によっては、メモリリークが発生し、結局、再起動って事で、余計時間がかかってしまう場合もあり、
あまり、使ってるのは見かけませんね。
ブラウザーは、結局、外の世界とつながるインターフェースだから、セキュリティも甘くなりますしね。

  • 2013/08/19(月) 11:25:20 |
  • URL |
  • 通りすがり #EBUSheBA
  • [ 編集 ]

Re: 通りすがり

え、できたんですか………。

Google Chrome を閉じた際にバックグラウンド アプリの処理を続行するという設定項目をONにしてみました。

これで常駐するのかな。

確かにメモリリークの問題はありますよね。

セキュリティ面は、ファイルのダウンロードが終われば通信を切るので大丈夫じゃないかと…。

そうですね。
よくよく、考えればブラウザーの脆弱性であって、
常駐による脆弱性ではないですね。
失礼しました。

WPFは、コンパイルできると思いますよ。
http://msdn.microsoft.com/ja-jp/library/vstudio/aa970678.aspx
http://wpf.keicode.com/basic/wpf4.php
的外れな回等であれば、ごめんなさい。

  • 2013/08/20(火) 10:50:32 |
  • URL |
  • 通りすがり #EBUSheBA
  • [ 編集 ]

Re: 通りすがり

ブラウザを常駐させているときは、何も開かないでいれば安全だと思いますね~。

WPFはコードだけでいけるみたいですね。
よく考えてみたら、WPFはXAMLと結びついているわけでは無いですもんね。

ただ、csc.exeでXAMLを使おうとすると、リソースにXAML(BAML?)を持って、それを読み込む機構を書かないといけなくて、面倒くさいようですね…。

そこで、MSBuild。結局、コマンドラインでやるならMSBuildですね。
VS付属のdevenv.exeというのもありますが、違いが分からない…。

csc.exeでやると、確かにめんどくさそう。
MSのこういう機能って、お試し実装、
流行れば、次回のバージョンでは、
簡単にっていうのが、繰り返されるので、
そのうち、楽にできるようになるのかも。。。
(案外、nugetで既にツールがあるかもしれません)

MSBuild、devenv.exeの違いは、devenvがレガシーの名残で、msbuildで統合されたって事かと。
詳しい解説は、以下に。
http://www.atmarkit.co.jp/fdotnet/special/msbuild01/msbuild01_01.html

最近知ったのですが、WPFとasp.netって同じチームが、
開発しているようですね。開発思想的なものが
似ていると思ってました。

  • 2013/08/21(水) 16:16:17 |
  • URL |
  • 通りすがり #EBUSheBA
  • [ 編集 ]

Re: 通りすがり

csc.exeはあくまでもコンパイラですからね~。
VSもMSBuildもCSharpCodeProviderも内部ではcsc.exeを参照しているんじゃないかと思うのですが。

devenv.exeよりもMSBuildを使ったほうがいいようですね。
スイッチだけじゃなく、MSBuildではビルド構成をXMLに書けるみたいですし。

しかも、MSBuildって.NET Frameworkに同梱なんですよね。
Windowsにも標準でこんな立派な開発環境があったのか…。

WPFとASP.NETの開発チームが同じとは驚きです!
WPFとSilverlightが同じなら分りますが、ASP.NETですか。
共通点が見つからない…。

asp.netと、WPFの共通点は、viewとcodeが分かれてて、
その書き型がそっくりですね、databindする時のやり方とか。
asp.net
<asp:TextBox ID="TBox" RunAt="Server"
Text='<%# Bind("Name") %>' />
WPF
<TextBlock Text="{Binding Name}" />

asp.netの方がHtmlに似せようとしてあるので、
記述が多くなってますが、やってる事は同じですね。
(裏のコード部分は、それぞれのクセが多いですね)
ASP.NETにはMVC、ネイティブはMVVMとなってますし。
(というか、MV~と言うのは、最近のトレンドですね)

  • 2013/08/22(木) 21:58:22 |
  • URL |
  • 通りすがり #EBUSheBA
  • [ 編集 ]

Re: 通りすがり

おお、なるほど。

確かに、UIがHTMLですから、その時点でViewとCodeが切り離されているようなものですよね。
HTMLがUIになるアプリケーションとMVVMの相性はすごく良さそうな気もしてきました。

HTMLといえば、XAML+C#って、今流行りのHTML5+JavaScriptと似てますね。
ただ、XAMLがUIと装飾を詰め込むのに対して、
HTMLの場合はCSSでやっていますから、よりやりやすいですね。

MV~がトレンドですか。それほどシステムが大規模化したってことですね。

アメリカの英語版のDirectX11.2解説ページで、特にXBOX ONE向けのアプリケーションを作る場合に、アプリケーションの紹介画面の実装はできればXAMLで…という風に書いてました。
要は3DSとかのタイトルロゴを模したものをさらに汎用マークアップ化したものと思います
ところで、XAMLと常駐やデータバインドって何の関係があるんですか・・・?

  • 2013/09/05(木) 16:26:30 |
  • URL |
  • あおみん #-
  • [ 編集 ]

Re: あおみん

ああ、常駐はXAMLと関係ないですね(笑)
ブラウザ常駐についての記事を、サブブログのほうに書いていまして、そのコメントが来ただけです。

> 要は3DSとかのタイトルロゴを模したものをさらに汎用マークアップ化したものと思います
XAMLはタイトルロゴ用のマークアップ言語ではないですね。
「できればXAMLで」というのは、あまり詳しくはないのですが、MSがXAML推しなだけかな…と。

XAMLは平たく言うと、WPFアプリケーションのUI配置を記述する言語です。
(UI以外にも、WFとかにも使われています。)

データバインドについては、WPFにデータバインドという機能があって、
WPFにデータバインドをさせるためにXAMLに書くだけのことですから、
XAMLとデータバインドは直接関係するわけではないといっても良いかも知れません。
ただ、XAMLでデータバインドさせるのは定番ですから、一緒に書いたわけです。

なるほど
ありがとうございます(>。<;

XAMLでアプリケーションロゴを…という理由についてですが
・ネット経由でのゲームカタログでXAMLだけをやりとりすることで、負荷が少ない
・本実装にも共通のXAMLを使うことになるので、ロゴと中身が大きく食い違うということが避けられる
・開発保守負担の軽減
などが列記されていました。まあ確かにマイクロソフト側の言い分には違いありません

伏せコメントが出来ないのでメールフォーム使いました
宜しければご一読ください

  • 2013/09/06(金) 00:07:14 |
  • URL |
  • あおみん #-
  • [ 編集 ]

Re: あおみん

すいません、DirectXのゲーム事情に詳しくないもので、よく分からないのですが…。
まぁ、Microsoftは今後、どんどんXAMLを押し出していく方針だと思います。

コメントの投稿

トラックバック

トラックバック URL
http://cyberboy6.blog.fc2.com/tb.php/292-6017797c
この記事にトラックバックする(FC2ブログユーザー)

当ブログをご利用(閲覧等)になる場合は必ず「当ブログの利用規定」をお守りください。