タイトル:Snoopを使いWPFを理解しよう(仮称) 特にWPFにおける依存プロパティ(DependencyPropety)をみることに最適なツールです。 TODO: ーーーーー ざっと操作の説明。 Ctrl+ShiftでMouseOverしてコントロールを指定する。 Enable/Disable mini viewを押して、elementを表示する。(Preview element) TreeViewの説明 ・Total number of visual children.の説明。 現在作っているプログラムは1000~3000(画面によって増減する) ProperTreeView(Property Grid)の説明。 テーマとスタイルの確認、このプロパティをいじるとどうなるの?が確認できる。 EventsView(RoutedEvents )の説明。 ーーーーー ・ValueSourceの説明。 Local,Unknown,Inherited,Default ↓詳しく説明しないけどこれだけ定義されているよ。 System.Windows.BaseValueSource Unknown, 通常のプロパティ Default, 標準 DefaultStyle, テーマ DefaultStyleTrigger, テーマ Style, スタイル StyleTrigger, スタイル Inherited, カスタム依存プロパティでプロパティ継承を有効にした場合。 おもな利用例としてはDataContext ImplicitStyleReference, ソースは、暗黙的なスタイルの参照 (スタイルは検出された型またはベースとなる型に基づく) です。 TemplateTrigger, ControlTemplate,Trigger ParentTemplate, 親から引き継いだもの。 ParentTemplateTrigger, 親から引き継いだもの。 Local, そこだけ限定のプロパティ、リソース、データバインド 依存関係プロパティ値の優先順位」を参照してください BaseValueSourceの値が高いほうが優先される。 Unknown = 0, Default = 1, Inherited = 2, DefaultStyle = 3, DefaultStyleTrigger = 4, Style = 5, TemplateTrigger = 6, StyleTrigger = 7, ImplicitStyleReference = 8, ParentTemplate = 9, ParentTemplateTrigger = 10, Local = 11, // ないけど実行中のアニメーションが一番強い。 ---- ・Toggle hiding defaulted properties. ここを僕は改造して使ってるよ。 TODO : この位置で依存プロパティについてデモを通じて説明。アタッチも。 ーーーー ・Scope up (after inspecting a value),Delveを押した後。 の説明。 ・Delve,Delve Binding,Delve BindingExpression,Clear/Reset. ・Search for Binding errors の説明。 TODO : この位置でデモを通じてDataBindingの説明。 ーーーーおまけ ・Set a breakpointの説明。 実際に止めてみる。デモ ーーーーまとめ。 ぜひ使ってみてください。 ーーーー xaml convert eventのdefault set。 ーーーーーーーーーーーーーーーーーーーーーppt今日作る。 勉強会資料作成。 EventManager ーーーーーーーーーーーーーーーーーーーーーwankuma k Snoop k ソースコードを全部見たい。 ・WPFのpptを作成する。snoop 何を報告するか。何を説明するか。 アタッチshowgridline Clear Filter Visuals with binding Errors PropertyGrid的に変更できる。 zommer mouse wheel. k xprを見てみる。 expression Designをダウンロードする。 k プロパティグリッドをみるツールを探す→ない。 k snoopではデペンデンシープロパティしか見えないの? 確認。 通常のプロパティとデペンデンシープロパティ コレクションをみるには適していない。 ValueSourceとしてはUnknownが普通のプロパティ k Blend削除。 x 都道府県のListBoxを使用する。 button 200個。CLR Profiler System.Forms.Button 380bytes System.Controls.Button 248bytes そんなことはなかった。 ----- http://msdn2.microsoft.com/ja-jp/library/ms746927(VS.90).aspx WPFの基礎を全部読む。 ----- ValueSourceの全部を確認。 http://msdn2.microsoft.com/ja-jp/library/system.windows.basevaluesource.aspx Windows Presentation Foundationプログラミング9.3 メモリ使用領域確認。(CLRProfiler) 再度図をつくる。 d1 System.ComponentModel.Component 20 bytes c1 Forms.Control 240 bytes b1 Forms.Button 380 bytes g2 Windows.DependencyObject 28 bytes f2 Windows.UIElement 208 bytes e2 Windows.FrameworkElement 240 bytes d2 Controls.Control 248 bytes c2 Controls.ContentControl 248 bytes b2 Controls.Button 248 bytes -- WPF Button b1 240 bytes CheckBox b2 248 bytes ComboBox b3 1.3kB Label b4 248 bytes ListBox b5 1.3kB ListView b6 1.3kB ProgressBar b7 256 bytes RadioButton b8 248 bytes RichTextBox b9 5.6kB TabControl b10 1.3kB TextBox b11 1.5kB Window b12 48kb? --- Form Button b1 380 bytes CheckBox b2 416 bytes ComboBox b3 464 bytes Label b4 392 bytes ListBox b5 404 bytes ListView b6 812 bytes ProgressBar b7 400 bytes RadioButton b8 428 bytes RichTextBox b9 432 bytes TabControl b10 412 bytes TextBox b11 388 bytes Forms b12 588 bytes 読み取り専用のカスタム依存プロパティ。→他のトリガにすることができる。 添付プロパティの確認。 インテリセンス確認。 propdp propa ・(XAMLブラウザアプリケーション)xbap使える? 再度確認C:\Documents and Settings\ymon\Documents\Works\Text\phaid\WPF\WPFSamples\Intro\QuickStart4\CSharp\obj\Debug\QuickStart4.xbap →やっぱり死亡。 ・またはマークアップのみの Extensible Application Markup Language (XAML) ページ)。でテスト。Loose XAML →やっぱり無理。IEの保護モード解除はためしていない。 ・シェアードデペンデンシープロパティの確認。 AddOwner ・12/20 VS2008を入れてみる。 http://schemas.microsoft.com/netfx/2007/xaml/presentation ・わからん。 C:\Program Files\Microsoft Visual Studio 8\xml\Schemas\XamlPresentation2006.xsd C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\ http://schemas.microsoft.com/winfx/2006/xaml/presentation http://schemas.microsoft.com/netfx/2007/xaml/presentation System.Windows.Data Warning: 47 : Created BindingExpression (hash=32762966) for Binding (hash=11766267) System.Windows.Data Warning: 49 : Path: 'ActualHeight' System.Windows.Data Warning: 51 : BindingExpression (hash=32762966): Default mode resolved to OneWay System.Windows.Data Warning: 52 : BindingExpression (hash=32762966): Default update trigger resolved to PropertyChanged System.Windows.Data Warning: 53 : BindingExpression (hash=32762966): Attach to System.Windows.Controls.Border.Height (hash=26431238) System.Windows.Data Warning: 57 : BindingExpression (hash=32762966): RelativeSource (FindAncestor) requires tree context System.Windows.Data Warning: 56 : BindingExpression (hash=32762966): Resolve source deferred System.Windows.Data Warning: 58 : BindingExpression (hash=32762966): Resolving source System.Windows.Data Warning: 61 : BindingExpression (hash=32762966): Found data context element: (OK) System.Windows.Data Warning: 64 : Lookup ancestor of type GridViewRowPresenter: queried ContentPresenter (hash=64875945) System.Windows.Data Warning: 64 : Lookup ancestor of type GridViewRowPresenter: queried GridViewRowPresenter (hash=47012596) System.Windows.Data Warning: 63 : RelativeSource.FindAncestor found GridViewRowPresenter (hash=47012596) System.Windows.Data Warning: 69 : BindingExpression (hash=32762966): Activate with root item GridViewRowPresenter (hash=47012596) System.Windows.Data Warning: 98 : BindingExpression (hash=32762966): At level 0 - for GridViewRowPresenter.ActualHeight found accessor DependencyProperty(ActualHeight) System.Windows.Data Warning: 94 : BindingExpression (hash=32762966): Replace item at level 0 with GridViewRowPresenter (hash=47012596), using accessor DependencyProperty(ActualHeight) System.Windows.Data Warning: 91 : BindingExpression (hash=32762966): GetValue at level 0 from GridViewRowPresenter (hash=47012596) using DependencyProperty(ActualHeight): '29' System.Windows.Data Warning: 71 : BindingExpression (hash=32762966): TransferValue - got raw value '29' System.Windows.Data Warning: 78 : BindingExpression (hash=32762966): TransferValue - using final value '29' GetHashCodeをsnoopに追加しておくと便利かもね。 ・通常のプロパティに対して、xamlで値を設定できるか→できないはず→できた。 DataBindingを設定したらやっぱりだめだった。 > XamlParseException > 型 'MyButton' の 'MyProperty' プロパティで 'Binding' を設定することはできません。'Binding' は、DependencyObject の DependencyProperty でのみ設定できます。 通常のプロパティに対して、リソースで値を設定できるか。→できないはず。 依存プロパティに対して、リソースで値を設定できるか。DynamicResource確認。 this.Resources["aaa"] = の形でも // object o = this.FindResource("aaa"); // SolidColorBrush s = o as SolidColorBrush; // s.Color = Color.FromRgb(0, 0, 0); の形でも反映してくれた。 StaticResourceでは反映してくれない。 ・コントロールではなくデータとして依存プロパティを使用してる?→デペンデンシーオブジェクトである必要がある。 コレクション型依存関係プロパティ http://msdn2.microsoft.com/ja-jp/library/aa970563(VS.80).aspx FreezableCollection Freezable ・優先順位があるのはわかるけど、優選順位を無視して取得できる仕組みはある? →ないかも。 ただ、依存関係プロパティ値の優先順位。http://msdn2.microsoft.com/ja-jp/library/ms743230(VS.80).aspx のサンプルコードは非常にいい例。 ・PresentationHostがManagedInjector.dllを保持し続けることがあるのでSnoopをビルドしなおしたいときはPresentationHostのプロセスを殺す。 ・カスタムのテーマって追加できる? http://d.hatena.ne.jp/Yamaki/20061106/1162787221 この方法でついかできるかな? ・どこのスタイルが適用されているかはわからないかな? Snoopでみて、Styleとれるかな? →わからない。 ・snoopをVS2008でコンパイルしたい。 ・TabItemのDataContextとして、TabControlのDataContextを継承できる? →あれ継承していた。 ・CLR Profilerも。 ・namespaceの違いはわからん。 ・WPF3.5の新しいものは? http://msdn2.microsoft.com/ja-jp/library/bb613588.aspx http://nobumatsu.cocolog-nifty.com/blog/2007/10/wpf_35_top10_c1f3.html http://blogs.msdn.com/hiroyuk/archive/2007/11/30/6604954.aspx ----- text snoopが使えるときの確認 スタイルとテーマの適用確認。 他人が作ったWPFアプリケーションを見る場合、どのDataContextをみているかをすぐに確認できる。 フォームズのとの対比。 リフレクションは使用していない。 ***ひたすら増やす。 どうしたいのかを実装する。 xamlファイルの書き出し。 XAMLWriter.Save パブリック以外の型はシリアル化できない。 http://msdn2.microsoft.com/ja-jp/library/ms750605(VS.90).aspx k EventRouted確認。 defaultEvents。 中途半端な知識でもsnoopを使えば何とかなります。 この隙間なにー!? いままでの通常のプロパティとどう違うのかという点を中心のお話したいなと思います。 依存プロパティによって実現される便利な概念について説明します。 またSnoopを使い、視覚的にみていただくことで理解が一層深まるのではないかと思います。 デバッグの手段などについてお話ししたいと思っています。 Snoopは便利だよ。 視覚的に見ることができるので、とても理解がはかどるのではないかと思います。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー では時間になりましたのではじめさせていただきたいと思います。 今日はsnoopを使いWPFを理解しましょうというタイトルで 30分お時間をいただいています。 まず私usayについてですが、 WPFを用い、いち早く業務アプリケーション開発を行っております。 WPFがRTMになった1年前から開発をスタートしたので、 もう1年が経過しております。 今日はその開発の中で一番役に立ったSnoopというツールを紹介します。 (えーVisualStudioとかを除いて一番役に立った) WPFの技術についてふれていただきたいと思います。 アジェンダの説明をします。 > ・Snoop(WPF向け)とは? まずSnoopというツールは何かという説明をします。 そのあとにざっと操作の説明をします。 > ・ざっと操作の説明。 えーそのあとに > ・依存プロパティ(Dependency Property)とは 依存プロパティとデータバインディングについて説明をしたいと思っています。 > ・データバインディングとは? > ・まとめ ーーーーー1分 > ・Snoop(WPF向け)とは? > ・パケットスニファではありません。 SolarisなどのOSで付属している同名のツールとは別物です。 その正体は、 > ・WPFアプリケーションのデバッグ用ツール。 何ができるのかというと、 > ・Spy++のようにメッセージ(event)を見ることができ、それに加えて、PropertyGridのように、プロパティの確認および、直接編集が行えるツールです。 PropertyGridとはあまり知られてはいないかもしれませんがSystem.Windows.Formsにあるコンポーネントの一つです。 このコンポーネントに対して、対象となるクラスのインスタンスを指定することによって VisualStudioのプロパティの画面と同様に プロパティの確認および編集が行えます。 x PropertyGridの内部的にはReflectionを多用していると思われますが、 Snoopでも同じようなことが行えます。 > WPFで開発をするなら必須ツール。いますぐQuickLunchに放り込むかショートカットを設定してください 私はQuickLaunchに設定しています。起動するときの合言葉も決めています。カモンスヌープ☆といってMouseをクリックして起動しています。 ーー > ・作者はpete blois氏。http://www.blois.us/blog/ ぺいと? > ・Expression toolsの開発メンバー > ・一応Snoopのツール自体はunofficial toolです。 これが重要ですが、 > ・Snoop自身もWPFで書かれていて、ソースコードが公開されています。ぜひ改造して使いましょう。 http://www.blois.us/Snoop/ 改造しなくても使えます。 ーーーーー2分 > ・ざっと操作の説明。 まずデバッグ対象となるアプリケーションを起動しておきます。 今回のサンプルはDataBindingLab.exeというWindows SDKに含まれているサンプルです。 Snoopを起動します。 アプリケーションのタイトルを選択してSnoopボタンを押します。 そうするとSnoopのメイン画面が起動します。 この画面ですね。 こちらのMagnifyボタンについては説明しません。なぜならば役に立たないからです。 メイン画面を起動したあとに Ctrl+Shiftキーを押しながらMouseOverすることにより、対象となるインスタンスをハイライトすることができます。 もしくはTextBlockについて調べたいのであれば、左上のここにクラス名を入力します。 Nameプロパティが設定されていれば、それを元にフィルタリングも可能です。 VisualTreeとよぶんですが、 WPFの場合、 テーマやStyleの適用場所がたくさんあり、さらにトリガやテンプレートやデータバインディングによって刻々とVisualTreeが更新されます。 なのでこの画面があると、非常に楽です。 ーーーーーー2分。 次にPropertiesのタブです。 調査したいインスタンスを指定することで、 そのインスタンスのプロパティをみることができます。 ValueSourceがUnknonwとなっているものが通常のプロパティ。 それ以外が後ほど説明しますが依存プロパティです。 このPropertiesのタブも左のTreeViewと同じようにフィルタリングすることができます。 #Backgroundと入力 そして、この画面で、プロパティの確認と編集が行えます。 ためしにBackgroundの変更を行ってみます。 Red Yellow Blue Whiteに戻す。 これによってこのプロパティの動作がわからない この画面で気軽に試行錯誤することが可能です。 あまり使ったことがないですが、breakpointも設定ができます。 ーーー2分 次にEventのタブです。 ご覧のとおりイベントをキャプチャすることが可能です。 いまこのsnoopはちょっとだけ改造して 上のチェックボックスがすべてついてしまっていますが、 通常は最低限のEventにチェックがついています。 このタブはあまり高度なことが行えませんが、 最低限どういったイベントがあるかとか、 どのインスタンスがイベントを止めているかといった確認がおこなえます。 もっと詳細なイベントの確認はWindows SDKに含まれるWPFPerf.exeを使用しましょう。 ーーー1分 これで今日話したいことはだいたい終了しましたが、これだけだと時間があまってしまうので、 次に、依存プロパティ( Dependency Property)とは? について説明しようと思います。 > プロパティをWPF内部で管理したもの。 > いままでのプロパティをCLRプロパティと呼んで区別をしたりします。 この呼び方は覚えなくていいです。 > 何ができるのか?……リソース、データバインディング、スタイル、アニメーション、メタデータのオーバーライド、プロパティ値の継承、WPFデザイナの統合。 何が強力になったのか。 リソースの指定が気楽に行えます。 x StaticResource、DynamicResourceというふたつの指定方法があります。 x DynamicResourceという指定方法でリソースを指定すると、リソースを変更した段階で、即座に反映されます。 データバインディング。これについては後で説明します。 スタイル。コントロールの外見ですね。それに加えて、トリガという機能がありまして、 DPはトリガの対象とトリガになることができます。たとえばMouseOver アニメーション。 WPFのアニメーションはどうやっているかというと、依存プロパティの値を変更しているだけです。 すごい簡単に説明しました。内部ではすごく複雑です。 > プロパティ値の継承 これはのちほどデモで説明しようと思います。 > メタデータのオーバーライド、、WPFデザイナの統合。 このへんは難しいので説明しません。 > 特定の状況下でのみ使用する依存プロパティがあっても値を設定しなければ、メモリ使用量が少ない。 これを少しsnoopでみてみましょう。 # DataBindingLab.exe。ここでValueSourceがDefaultとなっているものと、プロパティタブの□ボタンを押したときの動作の説明。 調べ方が正しいかどうかはあやしいので 印刷した資料にはありませんが、 左がWindows.Formsで、右がWPFのコントロールです。 サイズが減っているものもあり、サイズが増えているものもあります。 > 依存プロパティの特殊な形、添付プロパティ(アタッチドプロパティ) 正確には違うんですが、 > あるクラスが他のクラスに対して、プロパティを設定できる。A(使用するクラス)→B(使用されるクラス)の場合にのみに使用するプロパティ、Bにプロパティを実装しなくてよい。 具体例として一番使われているのがレイアウト情報ですね。 Windows.Formsでは、Panelがあってその中にButtonがあったときに、Buttonのクラス定義としてプロパティを作成し、xyの情報などを設定しました。 WPFではPanelのクラス定義としてアタッチドプロパティを作成し、Buttonにインスタンスに対して、設定することが可能です。 つまり、何を言いたいかと言うと、Buttonクラス定義が非常にシンプルになります。 ーーーーー5分 デモです。 二つデモを行いたいと思います。 ControlAnimationGallery.exe 「^」ボタンの説明。 Snoopはコントロールだけではなくプロパティに設定されたインスタンスの中を見ることができます。 ーーーーー1分 Demo3-http://msdn2.microsoft.com/ja-jp/library/ms743230(VS.80).aspxのソースコードみやすいように改造。 もうひとつ地味なデモを。 x デモといいながらソースコードですね。 このソースコードで、どのBackgroundが指定されるかわかりますか? 誰かに指定。 依存プロパティでしっておくと、はまることがすくないこととして、 依存プロパティの優先順位があります。 これについて詳しくは説明しませんが、 Defaultが一番弱く。 Themeがその次。 ThemeTrigger Styleその次。 StyleTrigger Localが一番強い。DataBinding。 x 正確にはこの上にAnimationとCoerce(こわーす)というのがあります。 これをきちんと把握することによって、望みのUIが作成が可能です。 ーーー4分。 データバインディングについて。 > MVCアーキテクチャのビューとモデルの接合点 > バインディングターゲット(ビュー)は依存プロパティのみ。 xすごい簡単に説明すると、 xDataContextに指定したインスタンスのプロパティに x{Binding Path=hogehoge}という構文でアクセスします。 x#もちろん別の指定の仕方もあります。 ようは、データを画面上に簡単に表示するための手段(決まり事)です。 この機能(データバインディング)を使うとコード量も少なくなるし、実装スピードも速くなる。 ただ、複雑なことをしようとすると、わけがわからなくなります。 > バインディングソース(モデル)がバインディングターゲット(ビュー)になぜか反映できないことがよく起こる。その場合にSnoopが利用できる。 #FrameworkElement.DataContext どこが邪魔をしてきちんとバインディングができていないかが視覚的にみることができます。 VisualStudioのDebugWindowにも表示されるのですが、それだけの情報だと、解決にとても時間がかかります。 ーーー1分。 デモ:DataBindingLab.exeで例外でるようにすこしだけ改悪したもの。 まず例外がVisualStudioのDebug画面で表示されたとします。 かもーんすぬーぷ。 左上のVisuals with binding Errorsという秘密のコマンドを入力すると、 BindingError。赤いラベルを表示させてみる。 どこのインスタンスが例外が発生しているかがわかればもう解決したも同然です。 Delve Binding Delve BindingExpressionの違い。 これとVisualTreeを見比べることで だいたい解決します。 ーーー2分。 WPF3.5限定ですが、 diag:PresentationTraceSources.TraceLevel="high" という添付プロパティを使用することで、さらに詳細な情報をみることができます。 デモ: ValueSouce:Inherit。プロパティ値の継承。通常は継承しないですが、そういう依存プロパティの定義方法があります。 DataContextについて ーーー4分 まとめ: > 今日はSnoopの使い方について説明しました。 中途半端な知識でもsnoopを使えば何とかなります。 > 依存プロパティについて説明しました。 特定の依存関係をもつことによって、手軽に強力な機能を実現できるプロパティ。 Microsoftはとてもいい名前をつけたと思います。 x これを理解することによってカスタムコントロールが作り放題です。 > データバインディングで例外が発生したときの対処法について説明しました。 ーーー1分