37

FindNameは私にとって壊れています:(

私が探しているオブジェクトはそこにあります。証拠があります。

シナリオは次のとおりです。

ToggleButton button = (ToggleButton)sender;
Popup popup = (Popup)button.FindName("popSelectIteration");

popupはnullですが、常にではありません。たまに。しかし、 null に設定されている場合でも、探している子がそこにいます。

null のときにブレーク ポイントを設定し、これら 2 つのスクリーンショットを取得しました。

これは、FindName が "popSelectIteration" に対して null を返す場所です。

しかし、時計を掘り下げると、そこに子供がいることがわかります。

それで、私は何が欠けていますか?FindName が見つからないのはなぜですか? スクリーン ショットからわかるように、これはタイミングの問題ではありません (FindName ウォッチは null ですが、ダイレクト パスは問題ありません)。

コントロールを見つけるより良い方法はありますか?

補足:問題のトグル ボタンの XAML に興味がある場合は、次の質問で見つけることができます: WPF - FrameworkElement - すべての子孫を列挙しますか? .


更新:これが失敗する場合と機能する場合がある理由を調べるために、いくつかの掘り下げを行いました。私は呼び出すアニメーションを持っていますNameScope.SetNameScope((DependencyObject)form, new NameScope());(完全なメソッドコードはこちら)。その呼び出しの直後に、FindName が失敗し始めます。

私はその電話を本当に理解していません。コードをコピーして貼り付けたと思います。とにかく、コメントアウトしました。しかし、これが失敗する理由を知りたいです。

4

8 に答える 8

43

視覚ツリーと論理ツリーの違いに関係していると思います。コントロールは論理ツリーにありますが、このコントロールのテンプレートがまだ適用されていない可能性があるため、FindName は有用なものを返しません。

ApplyTemplate(); を呼び出すことができます。最初にコンテナに。

これは、時々何かを返す理由も説明します。

于 2010-02-18T06:18:27.830 に答える
39

試す

LogicalTreeHelper.FindLogicalNode(button, "popSelectIteration");
于 2010-12-02T15:30:26.457 に答える
3

私は今同じ質問に会いましたが、私は次のような方法を使用します:

    #region Override - OnApplyTemplate

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        this.PART_ListViewLeft      = GetTemplateChild(cPART_ListViewLeft)      as ListView;
        this.PART_ListViewCenter    = GetTemplateChild(cPART_ListViewCenter)    as ListView;
        this.PART_ListViewRight     = GetTemplateChild(cPART_ListViewRight)     as ListView;

        this.PART_GridViewLeft      = GetTemplateChild(cPART_GridViewLeft)      as DsxGridView;
        this.PART_GridViewCenter    = GetTemplateChild(cPART_GridViewCenter)    as DsxGridView;
        this.PART_GridViewRight     = GetTemplateChild(cPART_GridViewRight)     as DsxGridView;
        if(this.PART_ListViewLeft!=null)
            this.PART_ListViewLeft      .AlternationCount = this.AlternatingRowBrushes.Count;
        if(this.PART_ListViewCenter!=null)
            this.PART_ListViewCenter    .AlternationCount = this.AlternatingRowBrushes.Count;
        if(this.PART_ListViewRight!=null)
            this.PART_ListViewRight     .AlternationCount = this.AlternatingRowBrushes.Count;
      //  ApplyTempleted = true;
        CreateColumnLayout();
    }
    #endregion

コントロールが動的に作成され、そのコンテナーの「可視性」が非表示または折りたたみに設定されている場合、コードthis.PART_ListViewLeft = GetTemplateChild(cPART_ListViewLeft) as ListView;は常に null を返します。これは、呼び出される前にデータテンプレートがまだ適用されていないためですOnApplyTemplate

于 2013-10-25T13:32:52.850 に答える
1

私の経験に基づいて、FindName関数の使用を避けることをお勧めします。特に、コントロールに適用されたDataTemplateで何かを見つけようとすると問題が発生します。代わりに、可能であれば (ソフトウェア アーキテクチャに基づいて) XAML で Popup を宣言し、それをリソースのように参照するか、Binding を使用して Model プロパティをその参照に設定します。幸運を。

于 2010-02-18T16:10:26.500 に答える
-1

使ってみてbutton.FindResource("popSelectIteration")

于 2013-04-03T13:47:16.523 に答える