web-dev-qa-db-ja.com

WPF:TabControlとDataTemplates

次のシナリオを理解したいだけです。 <TabControl>にバインドされたObservableCollection<TabViewModel>を実装している場合

データテンプレートなし

DataTemplatesがない場合、テキストWpfApplication1.TabViewModelがタブヘッダーとコンテンツに表示されます。 Ok私はこの部分を理解しています。

ちょうどItemTemplate

私がちょうど持っているとき

<TabControl.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding TabTitle}" />
        </StackPanel>
    </DataTemplate>
</TabControl.ItemTemplate>

次に、タブヘッダーがいっぱいになります。タブの内容はまだWpfApplication1.TabViewModelです。

ちょうどDataTemplate

<Window.Resources>に以下がある場合

<DataTemplate DataType="{x:Type local:TabViewModel}">
    <TextBox Text="{Binding Text}" />
</DataTemplate>

そのテンプレートがタブヘッダーを埋めます。

両方

両方がある場合、ItemTemplateはタブヘッダーを埋め、DataTemplateはタブコンテンツを埋めます。なぜこのすべての違い。 ItemTemplateDataTemplateは、もう一方が存在しない場合、タブヘッダーを埋めます。両方が存在する場合、ItemTemplateがヘッダーを埋め、DataTemplateがコンテンツを埋めます。

物事はうまくいきますが、かなり混乱しています。 <TabControl.HeaderTemplate>のようなものがヘッダーを埋め、<TabControl.ItemTemplate>がコンテンツを埋めるのではないでしょうか?

33
Jiew Meng

まず、2つのテンプレートがここに含まれています。

  • TabControl.ItemTemplateTabItemヘッダーのレンダリングに使用
  • TabControl.ContentTemplateTabItemコンテンツのレンダリングに使用

これらのプロパティを明示的に設定しない場合、WPFは他の場所でそれらを解決しようとします。論理ツリーを上に移動して、ビューモデルのレンダリング方法を伝えるリソースを探します。一致するDataTemplateがあるがキーがないDataTypeが見つかった場合、それを使用してビューモデルをレンダリングします。見つからない場合は、デフォルトでオブジェクトのToString値がレンダリングされます。

したがって、明示的にしたい場合は、次のようなものが必要です。

<TabControl ItemsSource="{Binding Tabs}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

あなたは具体的ではないので、WPFは論理ツリーをたどって適切なDataTemplateを見つけようとします。それが見つかると、それを使用してビューモデルをレンダリングします。見つからない場合は、ToStringを呼び出してレンダリングします。

したがって、特定のケースに対処するには:

Just ItemTemplate

タブヘッダーをレンダリングする方法を明示的に説明しましたが、タブコンテンツはレンダリングしません。したがって、前者は提供されたDataTemplateを使用してレンダリングされますが、後者はデフォルトでToStringになります。

Just DataTemplate

タブヘッダーまたはタブコンテンツのレンダリング方法を明示的に指定していません。したがって、WPFは両方に対して適切なDataTemplateを検索します。どちらにもビューモデルのインスタンス(つまりDataContext)が含まれているため、同じDataTemplateがタブヘッダーとそのコンテンツのレンダリングに使用されます。

注:これがあなたの質問で起こっていることであると明示的に述べていませんでした。私が間違っている場合は私を訂正してください。

両方

この場合、タブのヘッダーではなくタブのコンテンツをレンダリングする方法を明示的に説明しました。したがって、タブヘッダーには明示的なDataTemplateが使用され、タブの内容には暗黙的なDataTemplateが使用されます。

54
Kent Boogaart