7

次のユーザー コントロールがあります。

<TabItem 
    x:Name="Self"
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    >
    <TabItem.Header>
        <!-- This works -->
        <TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/>
    </TabItem.Header>
    <TabItem.ContentTemplate>
        <DataTemplate>
            <!-- This binds to "Self" in the surrounding window's namespace -->
            <TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/>

このカスタム TabItem はDependencyProperty、インターフェイスを実装するために「ShortLabel」を定義します。TabItem内からこれと他のプロパティにバインドしたいと思いますDataTemplate。しかし、奇妙な相互作用により、TextBlock内のは の親コンテナーDataTemplateバインドされます。これは "Self" とも呼ばれますが、別の Xaml ファイルで定義されています。TabItem

質問

TabItem.Header ではバインディングが機能するのに、TabItem.ContentTemplate 内では機能しないのはなぜですか? また、DataTemplate 内からユーザー コントロールのプロパティにアクセスするにはどうすればよいですか?

私がすでに試したこと

  • TemplateBinding: の内部で ContentPresenter にバインドしようとしTabItemます。
  • FindAncestor, AncestorType={x:Type TabItem}TabItem:親が見つかりません。タイプを指定すると、これも機能しませんMyTabItem
  • ElementName=Self: 間違ったスコープ (親コンテナーではなく) でその名前のコントロールにバインドしようとしTabItemます。なぜこれが機能しないのか、ヒントが得られると思います.DataTemplateは、XAMLで定義された時点では作成されませんが、明らかに親コンテナーによって作成されます。

ControlTemplate探している効果を達成するために全体を置き換えることができると思いますTabItemが、全体を維持することなくのデフォルトのルック アンド フィールを維持ControlTemplateしたいので、そうするのは非常に気が進まないのです。

編集

一方、問題は次TabControlのとおりであることがわかりました。理由を説明するスレッドが MSDN フォーラムにあります。ItemsTemplateDisplayMemberPathItemsSourceVisual

これは WPF の TabControl の根本的な問題のようですので、質問を締め切らせていただきます。ご助力いただきありがとうございます!

4

2 に答える 2

2

問題のように見えるのは、コンテンツ プロパティを実際に使用せずに ContentTemplate を使用していることです。ContentTemplate の DataTemplate のデフォルトの DataContext は、TabItem の Content プロパティです。ただし、私が言ったことのどれも、バインディングが機能しない理由を実際に説明していません。残念ながら、決定的な答えを出すことはできませんが、TabControl が ContentPresenter を再利用してすべてのタブ項目のコンテンツ プロパティを表示することが原因であると推測されます。

したがって、あなたの場合、コードを次のように変更します。

<TabItem
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    Header="{Binding ShortLabel, RelativeSource={RelativeSource Self}}"
    Content="{Binding ShortLabel, RelativeSource={RelativeSource Self}}" />

ShortLabel が単なる文字列ではなく、より複雑なオブジェクトである場合は、ContentTemplate を導入する必要があります。

<TabItem
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    Header="{Binding ShortLabel, RelativeSource={RelativeSource Self}}"
    Content="{Binding ComplexShortLabel, RelativeSource={RelativeSource Self}}">
    <TabItem.ContentTemplate>
        <DataTemplate TargetType="{x:Type ComplexType}">
            <TextBlock Text="{Binding Property}" />
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>
于 2008-11-01T06:48:29.307 に答える
1

これを試して。うまくいくかどうかは定かではありませんが、

<TabItem 
    x:Name="Self"
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    >
    <TabItem.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=ShortLabel}"/>
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>

うまくいかない場合は、<TabItem/> にこの属性を追加してみてください。

DataContext="{Binding RelativeSource={RelativeSource self}}"
于 2008-10-08T19:58:57.500 に答える