2

バックグラウンド

FindResourceメソッドを使用したリソースのフェッチは、コントロールのコンストラクターから実行した場合は常に null を返すため、機能しないことを私は知っています。

public class MyButton : Button
{
    public MyButton()
    {
        Style = FindResource("myStyle") as Style;
    }
}

OnApplyTemplateメソッドを使用して実行できることはわかっています。

public override void OnApplyTemplate()
{
    Style = FindResource("myStyle") as Style;
    base.OnApplyTemplate();
}

質問

なんで?VisualTreeの読み込みと関係があると思いますが、WPF の専門家から、より詳細で正確な回答 (または、ここで完全にオフになっている場合は正しい回答) を得たいと思っていました。

4

1 に答える 1

4

リソースを見つけるには、(先祖に関連付けられたリソースを見つけるために) 論理要素ツリーをたどるかResources、現在の要素の を調べることが最も必要なためです。

Parentどちらの場合も、またはResourcesそれぞれが「正しい」値に設定されていない限り、これは不可能です。これらはプロパティであり、コンストラクターの実行後に XAML シリアル化エンジンによって設定されます。つまり、あなたが書くとき

<Button Height="80" Width="150" />

XAML デシリアライザーは、最終的に次のことと同等のことを行います

var button = new Button(); // element is instantiated
button.Height = 80;        // ...and THEN properties are set
button.Width = 150;

したがって、設定されているプロパティに依存するコンストラクター内では何もできません。

上記を裏付けるために、のドキュメントからFindResource:

呼び出し元の要素でリソースが見つからない場合は、論理ツリー内の親要素が次に検索され、次にアプリケーション、テーマ、最後にシステム リソースが検索されます。この検索方法は、リソースがマークアップの動的リソース参照によって要求された場合のツリーの検索方法と同じです。

もちろん、論理ツリーのウォークはParentプロパティを通じて行われます。これは直感的ですが、次のドキュメントにも明確に記載されていますLogicalTreeHelper.GetParent

このメソッドは、 orプロパティの適切な型バージョン (FrameworkElementまたはFrameworkContentElement) を取得する単なるラッパーです。そのため、現在のタイプを判別できない場合を除き、代わりにそれぞれのインスタンス プロパティを確認することをお勧めします。FrameworkElement.ParentFrameworkContentElement.Parent

于 2013-10-14T15:14:14.470 に答える