Warum Registerkarte Header im Inhaltsbereich der Registerkarten in einem XAML TabControl angezeigt?

StackOverflow https://stackoverflow.com/questions/1226622

Frage

Ich habe ein TabControl , dessen Itemssource gebunden ist, zu einer beobachtbaren Sammlung von Ansichten (Usercontrols), die jeweils die als Wurzelelement hat ein TabItem . Wenn es jedoch angezeigt wird, die Rubrik Text ist in Inhalt jeden TabItem, als ob Usercontrol Wrapper verursachen Konflikte:

Das TabControl ist in SmartFormView.xaml:

<UserControl x:Class="TestApp.Views.SmartFormView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel
        Margin="10">
        <TextBlock Text="{Binding Title}"
            FontSize="18"/>
        <TextBlock Text="{Binding Description}"
            FontSize="12"/>

        <TabControl
            Margin="0 10 0 0"
            ItemsSource="{Binding SmartFormAreaViews}"/>
    </StackPanel>
</UserControl>

Was muss ich ändern, damit TabItems als TabItems innerhalb des TabControl angezeigt werden?

Hier werden die TabItem Ansichten genannt SmartFormAreaView.xaml:

<UserControl x:Class="TestApp.Views.SmartFormAreaView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TabItem Header="This is the header">
        <StackPanel Margin="10">
            <TextBlock Text="this is the content"/>
        </StackPanel>
    </TabItem>
</UserControl>

Und hier ist, wo ich erstellen und laden jede Ansicht in die ObservableCollection :

var areas = from area in xmlDoc.Descendants("area")
            select area;
foreach (var area in areas)
{
    SmartFormArea smartFormArea = new SmartFormArea();
    smartFormArea.IdCode = area.Attribute("idCode").Value;
    smartFormArea.Title = area.Attribute("title").Value;
    SmartFormAreaPresenter smartFormAreaPresenter = new SmartFormAreaPresenter(smartFormArea);
    SmartFormAreaViews.Add(smartFormAreaPresenter.View as SmartFormAreaView);
}
War es hilfreich?

Lösung

Für jedes Item, wenn die Elemente in seine Sammlung Items hinzugefügt (entweder direkt oder über Itemssource) sind nicht Instanz dieses Elements Container Kontrolle, dann jedes Element wird in einer Instanz des Elements Behälters gewickelt. Der Artikel Behälter ist eine Klasse, wie TabItem oder ListBoxItem. Der Artikel Behälter ist normalerweise ein Content oder HeaderedContentControl, und dem tatsächlichen Artikel in seine Content-Eigenschaft zugeordnet, so dass Sie Vorlagen usw. verwenden können, um zu steuern, wie der Inhalt dargestellt wird. Sie können auch den Elementcontainer Stil selbst die ItemContainerStyle Eigenschaft ItemControl verwendet wird.

In diesem speziellen Fall sollten Sie Itemssource auf eine Liste von SmartFormAreaPresenters binden. Dann so etwas wie dies für die Registerkarte Steuerung verwenden:

<TabControl ItemsSource="{Binding SmartFormAreaPresenters}">
  <TabControl.ItemContainerStyle>
    <Style TargetType="{x:Type TabItem}">
      <Setter Property="Header" Value="{Binding HeaderText}" />
    </Style>
  </TabControl.ItemContainerStyle>

  <TabControl.ContentTemplate>
    <DataTemplate DataType="{x:Type local:SmartFormAreaPresenter}">
      <local:SmartFormAreaView />
    </DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>

Dabei gilt Header eine geeignete Eigenschaft auf Ihrem SmartFormAreaPresenter. Sie sollten auch die TabItem aus Ihrer SmartFormAreaView Definition entfernen. Die Datacontext jeder Ansicht werden automatisch auf den entsprechenden Presenter eingestellt werden.

Siehe Dr. WPF Blog für eine ausgezeichnete Diskussion verschiedenen Items verwandte Themen.

Andere Tipps

Die TabControl Ihre Kontrollen als Kontrollen nur akzeptieren, wenn sie geworfen werden kann, um TabItem, nicht Usercontrol oder SmartFormAreaView, etc.

Also entweder Sie regelmäßig TabItems mit visueller Struktur füllen, oder Sie Unterklasse TabItems, oder Sie Unterklasse der TabControl auf seinen IsItemItsOwnContainerOverride Methode, Ihre Art als Container zu übernehmen.

Das Verfahren soll wie folgt aussehen:

protected override bool IsItemItsOwnContainerOverride(object item)
{
    return item is YourControlTypeHere || item is TabItem;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top