2008-12-01 4 views
0

J'ai un onglet WPF TabControl avec deux éléments TabItems. Chaque TabItem contient un ListBox avec une ObservableCollection séparée en tant que ItemsSource. Chaque ListBox a un ItemTemplate différent.L'application se bloque lors de la modification des onglets qui contiennent ListBoxes avec ItemTemplates

Quel que soit TabItem que j'ai défini pour être sélectionné au démarrage, cet onglet s'affichera bien, mais lorsque je clique sur l'autre onglet l'application se bloque avec une erreur «Exception a été levée par la cible d'un appel» vers le DataTemplate pour l'onglet que je suis en train de changer.

Si je retire ItemTemplate de la zone de liste dans l'onglet Je suis en train de passer à (et utiliser DisplayMemberPath) tout fonctionne bien.

Cependant, si j'utilise un DataTemplate, que ce soit en ligne ou en StaticResource ou DynamicResource, il provoque le crash sur la commutation de tabulation.

Des idées? Pseudo-code suivant:


<Window x:Class="Example.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:objects="clr-namespace:Example.CoreObjects" 
    xmlns:controls="clr-namespace:Example.Controls" 
    > 
<Window.Resources> 
    <DataTemplate x:Key="ItemTemplateOne"> 
     <controls:CustomControlOne /> 
    </DataTemplate> 
    <DataTemplate x:Key="ItemTemplateTwo"> 
     <controls:CustomControlTwo /> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <TabControl Name="tabControl1"> 
     <TabItem Header="TabOne"> 
      <Grid> 
       <ScrollViewer> 
        <ListBox Name="ListBoxOne" 
          ItemsSource="{Binding}" 
          ItemTemplate="{StaticResource ItemTemplateOne}" 
          > 
         <ListBox.ItemsPanel> 
          <ItemsPanelTemplate> 
           <WrapPanel /> 
          </ItemsPanelTemplate> 
         </ListBox.ItemsPanel> 
        </ListBox> 
       </ScrollViewer> 
      </Grid> 
     </TabItem> 
     <TabItem Header="TabTwo"> 
      <Grid> 
       <ScrollViewer> 
        <ListBox Name="ListBoxTwo" 
          ItemsSource="{Binding}" 
          ItemTemplate="{StaticResource ItemTemplateTwo}" 
          > 
         <ListBox.ItemsPanel> 
          <ItemsPanelTemplate> 
           <WrapPanel /> 
          </ItemsPanelTemplate> 
         </ListBox.ItemsPanel> 
        </ListBox> 
       </ScrollViewer> 
      </Grid> 
     </TabItem> 
    </TabControl> 
</Grid> 

publique Window1() { InitializeComponent();

ListBoxOne.DataContext = ObservableCollectionOne; 
CollectionViewOne = CollectionViewSource.GetDefaultView(ObservableCollectionOne); 
CollectionViewOne.SortDescriptions.Add(new SortDescription("SortProperty", ListSortDirection.Descending)); 

ListBoxTwo.DataContext = ObservableCollectionTwo; 
CollectionViewTwo = CollectionViewSource.GetDefaultView(ObservableCollectionTwo); 
CollectionViewTwo.SortDescriptions.Add(new SortDescription("SortProperty", ListSortDirection.Descending)); 

}

Répondre

1

Quel que soit le TabItem je me mis à sélectionner au démarrage, cet onglet sera affiché très bien, mais quand je clique sur l'autre onglet l'application se bloque avec une « exception a été levée par la cible d'un appel » erreur pointant vers le DataTemplate pour l'onglet que je suis en train de changer.

Activez les exceptions de première chance, afin que vous puissiez trouver l'exception réelle au lieu de l'exception externe encapsulée - ce qui ne va pas sera beaucoup plus clair.

+0

J'ai creusé dans la trace de la pile et j'ai découvert mon erreur stupide. Les deux DataTemplates utilisaient chacun des contrôles personnalisés avec des propriétés très similaires. J'ai copié et collé le code DependencyProperty du contrôle personnalisé one au contrôle personnalisé deux, mais j'ai oublié de changer le type par lequel il a été enregistré. – bjh

0

Je pense que le problème est que ItemSource = "{} liaison" des deux ListBox. Je pense que cela dit de se lier à DataContext de la fenêtre, mais dans le code que vous définissez séparément.

Essayez déclarant un CollectionViewSource (ou deux si vous voulez différentes sortes entre ListBoxes) dans votre Window.Resources. Définissez votre Observablecollection comme source de CollectionViewSource.

Puis, dans vos ListBoxes, effectuez une liaison à la source CollectionView.

Si cela ne fonctionne pas, vous pouvez essayer de mettre chaque ListBox et ses ressources de données associées dans UserControls séparés.

Questions connexes