C#+WPFチューニング戦記

C#とWPFで高速なコードと最適なシステムを書くためにやってきたいろいろな事を書いてみます。.NET Frameworkのソースコードを読み解きましょう。なお、ここに書かれているのは個人の見解であって何らかの団体や企業の見解を代表するものではありません。

UIElementやFrameworkElementの派生クラスのサイズ

UIElementやFrameworkElementや他のコントロール群。それらのサイズを決めるものは何でしょうか。

WidthやHeightはサイズを決めるものではなく、コントロールの使用者がどのようなサイズを期待しているか、標準の測定ロジック(すなわちMeasure)に知らせるための箱に過ぎません。

サイズを決めるのは、Measureで設定されるDesiredSizeです。そして親パネルのMeasureとArrangeがそれをどのように料理するかです。

これはつまり、UIElementならMeasureCore、FrameworkElementならMeasureOverrideということになります。そこで大胆にWidthやHeightを無視して異なるサイズを設定しても何ら問題は生じません。

MaxWidthやMinWidthすら、標準の測定ロジックの便宜のために存在しているのみです。この周辺を読むと、そのあたりも読むことができます。

http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/FrameworkElement.cs#4288

http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/FrameworkElement.cs#4019

 

ただし「独自の測定ロジックを実装する必要」ということは明確なシナリオのイメージが求められます。例えば、そのコントロールは汎用でしょうか、でしたら汎用の測定ロジックを変えないのが望ましいはずです。

特定のパネルの専用コントロール、というシナリオにおいて、おそらくこの専用の測定ロジックというものが活きてくると考えられます。

こうした場合、どのような記述をすればよいでしょうか。

WPF内でもポピュラーな記述方法としては、VisualTreeHelperにより親Visualを取得し、その型をチェックしてから標準ロジックか独自ロジックを選ぶという形になります。

あと、少し興味深いのはMeasureに関してはレイアウトパス外からの使用をしても問題がありません。

このあたりの話はまた別のときに。