20

を持っ{Binding ElementName=foo}ている場合、視覚ツリーまたは論理ツリーを検索しますか?

WPF の論理ツリーとビジュアル ツリーについて | データを見る、データする

論理ツリーが重要になるのはいつですか?

{Binding ElementName=Foo} などで名前を検索すると、継承可能なプロパティの場合と同じように、名前の範囲を検索するために祖先が検索されます。

アタッチされた動作による Silverlight での ElementName バインディング

これを有効にするために、WPF は ElementName および RelativeSource バインディングを提供し、ビジュアル ツリー内の他の要素を見つけてバインドするための強力なメカニズムを提供します。

編集:

によるバインドに使用される論理ツリーのように見えますElementName

引数#1。

MSDN の記事FrameworkElement Classによると:

FrameworkElement は UIElement を拡張し、次の機能を追加します。

  • データ バインディングと動的リソース参照のサポート: データ バインディングとリソースのプロパティ レベルのサポートは、DependencyProperty クラスによって実装され、プロパティ システムに具体化されますが、式 (プログラミング構造) として格納されているメンバー値を解決する機能データ バインディングと動的リソースの両方の基盤となる) は、FrameworkElement によって実装されます。詳細については、「データ バインディングの概要」および「リソースの概要」を参照してください。

引数#2。

ElementNameを指してx:Nameいるので、この名前は何らかの方法で見つける必要があります。NameScopeの概念があります。

ほとんどのシナリオでは、FrameworkElement および FrameworkContentElement で公開されている FindName メソッドは、名前で要素を検索するために呼び出すより適切なメソッドです。FrameworkElement および FrameworkContentElement によって公開される Name プロパティは、初期名をマークアップ属性として設定するために使用するより適切なプロパティです。また、FrameworkElement および FrameworkContentElement で公開されている RegisterName メソッドは、名前を特定の名前スコープに確立するために必要です (これを直接実行できる NameScope メンバーはありません。RegisterName を使用するには、最初に現在の名前スコープを設定する必要があります)。

一方、Visual クラスにはメソッドがなく、 INameScopeFindNameも実装されていません。

4

2 に答える 2

6

論理ツリーだと思います。ControlTemplates を使用する場合、あるビジュアル ツリーを別のツリーに置き換えますが、ControlTemplate 内で定義された名前を参照できるとは思いません。

例えば:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.Resources>
            <ControlTemplate x:Key="Foo" TargetType="Button">
                <Border x:Name="border" Background="Red">
                    <Label Content="{TemplateBinding Content}"></Label>
                </Border>
            </ControlTemplate>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button x:Name="buttonFoo" Background="Green" HorizontalAlignment="Center" VerticalAlignment="Center" Template="{DynamicResource Foo}">Foo</Button>
        <Label x:Name="labelBar" Grid.Column="1"  HorizontalAlignment="Center" VerticalAlignment="Center" Background="{Binding ElementName=border, Path=Background}">Bar</Label>
    </Grid>
</Page>

ControlTemplate で「border」という名前の要素が見つかりませんが、labelBar のバインディングの ElementName を「buttonFoo」に変更すると、予想どおり背景が緑になります。

于 2009-05-22T19:13:26.267 に答える
0

ある意味でのバインドのElementNameプロパティ(以下の回答を参照)は、Xaml の論理ツリーのみで特定のコントロールを推測するために使用しているため、論理ツリーから離れて機能します。ElementName

視覚ツリーまたは論理ツリーを検索しますか?

あなたが提案する前提は間違っています。どちらのツリーにもルックアップ自体はありません。1 つは、継承された論理ツリーにデフォルト設定する代わりに、バインディングで使用されるリフレクション操作のSourceプロパティを設定するだけです。DataContext

Binding.ElementName Property (System.Windows.Data)のドキュメントを読んだ場合(太字の鉱山):

「... ElementName プロパティは、Binding のソースを明示的に設定し、継承されたデータ コンテキストをオーバーライドできる方法の 1 つです。」

ソースは、現在のオペレーション名前空間内にあるインスタンス化されたオブジェクトであり、アクセスして反映することができます。

Xaml で論理項目に名前を付けるだけでなく、ビジュアル ツリーにも存在する可能性があるため、おそらく論理ツリーに存在する可能性が高くなります (ただし、論理ツリーには存在しません) 。


詳細については、「データ バインディングの概要」を参照してください。

于 2016-07-06T15:50:31.570 に答える