Por que cabeçalhos de guia exibido na área de conteúdo de separadores em uma XAML TabControl?

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

Pergunta

Eu tenho um TabControl , cujo ItemsSource está ligado a uma coleção observável de pontos de vista (UserControls) cada qual tem como seu elemento raiz TabItem . No entanto, quando ele é exibido, o Header o texto está no conteúdo de cada TabItem, como se UserControl invólucro está causando conflitos:

text alt

O TabControl está em 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>

O que eu tenho que mudar para que TabItems são exibidos como TabItems dentro do TabControl?

Aqui estão os pontos de vista TabItem chamado 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>

E aqui é onde eu criar e carregar cada vista para o 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);
}
Foi útil?

Solução

Para qualquer ItemsControl, se os itens adicionados à sua colecção de itens (quer directamente ou através de ItemsSource) não são exemplo de recipiente de produto que de controlo, em seguida, cada produto é enrolado em um exemplo do recipiente de produto. O recipiente de produto é uma classe, tais como TabItem ou ListBoxItem. O contêiner de item normalmente é um ContentControl ou HeaderedContentControl, e seu item real é atribuído a sua propriedade de conteúdo, de modo que você pode usar modelos etc para controlar como o conteúdo é apresentado. Você também pode estilo do próprio contêiner de item usando a propriedade ItemContainerStyle do ItemControl.

Neste caso particular, você deve ligar ItemsSource a uma lista de SmartFormAreaPresenters. Em seguida, use algo como isto para o controle guia:

<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>

onde HeaderText é um imóvel adequado em seu SmartFormAreaPresenter. Você também deve remover o TabItem de sua definição SmartFormAreaView. O DataContext de cada exibição será automaticamente definido para o Presenter apropriada.

Veja do Dr. WPF blogue para uma excelente discussão de vários temas relacionados ItemsControl.

Outras dicas

O TabControl aceitará seus controles como seus controles somente se pode ser convertido para TabItem, não UserControl, ou SmartFormAreaView, etc.

Assim que você quer preencher TabItems regular com sua árvore visual, ou você subclasse TabItems, ou você subclasse o TabControl para substituir sua IsItemItsOwnContainerOverride método, a aceitar o seu tipo do recipiente.

O método deve ter a seguinte aparência:

protected override bool IsItemItsOwnContainerOverride(object item)
{
    return item is YourControlTypeHere || item is TabItem;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top