2010-09-24 4 views
3

Je souhaite créer un TabControl avec un certain nombre de TabItems «statiques» (explicitement typés en XAML) et un certain nombre de TabItems ajoutés dynamiquement. Pour y parvenir, j'ai essayé d'utiliser un CompositeCollection comme TabControl.ItemSource.Liaisons à l'intérieur de CompositeCollection

Exemple de code:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     > 
    <Window.Resources> 
    <x:Array x:Key="SomeTexts" x:Type="sys:String"> 
     <sys:String>Text1</sys:String> 
     <sys:String>Text2</sys:String> 
    </x:Array> 
    </Window.Resources> 

    <TabControl> 
    <TabControl.ItemsSource> 
     <CompositeCollection> 
     <TabItem Header="Test"> 
      <StackPanel> 
      <TextBlock x:Name="MyText" Text="Blah" /> 
      <TextBlock Text="{Binding Text, ElementName=MyText}" /> 
      </StackPanel> 
     </TabItem> 
     <CollectionContainer Collection="{StaticResource SomeTexts}" /> 
     </CompositeCollection> 
    </TabControl.ItemsSource> 
    </TabControl> 
</Window> 

Cet exemple a un élément de patte fixe et trois éléments de l'onglet « dynamiques » (notez que « SomeTexts » est un tableau fixe ici juste pour faciliter l'exemple, dans le code réel, il sera une collection dynamique).

L'exemple fonctionne à l'exception de la liaison 'ElementName', qui ne fonctionne pas. Je suppose que c'est parce que le CompositeCollection n'est pas un Freezable (voir aussi Why is CompositeCollection not Freezable?).

Est-ce que quelqu'un a une solution?

Répondre

1

J'avais un scénario similaire. Pour résoudre ce problème, j'ai trouvé le following article.

Ce message explique comment créer un objet proxy freezable auquel vous pouvez définir votre contexte de données. Vous ajoutez ensuite ce proxy en tant que ressource pouvant être référencée en tant que ressource statique. Voir les éléments suivants:

public class BindingProxy : Freezable 
{ 
    public static DependencyProperty DataContextProperty = DependencyProperty.Register(
     "DataContext", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 

    public object DataContext 
    { 
     get { return GetValue(DataContextProperty); } 
     set { SetValue(DataContextProperty, value); } 
    } 

    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 
} 

Cela peut ensuite être utilisé dans votre XAML comme ceci:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     xmlns:y="clr-namespace:Namespace.Of.BindingProxy" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     > 
    <Window.Resources> 
    <x:Array x:Key="SomeTexts" x:Type="sys:String"> 
     <sys:String>Text1</sys:String> 
     <sys:String>Text2</sys:String> 
    </x:Array> 
    <y:BindingProxy x:Key="Proxy" DataContext="{Binding}" /> 
    </Window.Resources> 

    <TabControl> 
    <TabControl.ItemsSource> 
     <CompositeCollection> 
     <TabItem Header="Test"> 
      <StackPanel> 
      <TextBlock x:Name="MyText" Text="Blah" /> 
      <TextBlock Text="{Binding DataContext.SomeProperty, Source={StaticResource Proxy}}" /> 
      </StackPanel> 
     </TabItem> 
     <CollectionContainer Collection="{StaticResource SomeTexts}" /> 
     </CompositeCollection> 
    </TabControl.ItemsSource> 
    </TabControl> 
</Window>