2010-06-07 9 views
3

Silverlight ne prend pas en charge les modèles d'éléments alternés dans ItemsControl. J'ai quelques idées en tête quant à la façon d'accomplir cela, mais pour éviter de polluer les réponses possibles, je les laisserai de côté.Silverlight ItemsControl avec Alternate ItemTemplate

L'idée est la même que celle d'un ItemTemplate normal, car il ne dépendra de rien dans le contexte de données liées de fonctionner. Je voudrais que la fonctionnalité reste dans la vue (en supposant que MVVM)

Si vous deviez concevoir une méthode de fournir des modèles alternatifs (et je veux dire un modèle de données complet) pour un ItemsControl, comment accompliriez-vous ceci?

Répondre

3

Etendre ItemsControl et dans le remplacement PrepareContainerForItemOverride, vous pouvez appliquer des modèles alternés.

 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 
    { 
     if (!object.ReferenceEquals(element, item)) 
     { 
      ContentPresenter presenter = element as ContentPresenter; 
      ContentControl control = null; 
      if (presenter == null) 
      { 
       control = element as ContentControl; 
       if (control == null) 
       { 
        return; 
       } 
      } 
      DataTemplate itemTemplate = null; 
      if ((this.ItemTemplate != null) && (this.DisplayMemberPath != null)) 
      { 
       throw new InvalidOperationException("Cannot set ItemTemplate and DisplayMemberPath simultaneously"); 
      } 
      if (!(item is UIElement)) 
      { 
       if (this.ItemTemplate != null) 
       { 
        if(this.AlternateItemTemplate != null && ((alternationIndex % 2)) == 1) 
         itemTemplate = this.AlternateItemTemplate; 
        else 
        itemTemplate = this.ItemTemplate; 
        alternationIndex++; 
       } 
      } 
      if (presenter != null) 
      { 
       if (itemTemplate != null) 
       { 
        presenter.Content = item; 
        presenter.ContentTemplate = itemTemplate; 
       } 
       else 
       { 
        presenter.SetBinding(ContentControl.ContentProperty, new Binding(this.DisplayMemberPath)); 
       } 
      } 
      else 
      { 
       control.Content = item; 
       control.ContentTemplate = itemTemplate; 
      } 
     } 
    } 

La façon dont je me sers alternationIndex n'est pas très précis et aurait besoin d'être changé, mais sinon cela devrait fonctionner.

1

Je voudrais mettre une propriété Bool dans la classe Item ViewModel et écrire DataTrigger sur le ItemTemplate pour donner un aspect différent. Dans la collection, nous pouvons passer en boucle et définir cette variable de manière appropriée

+0

Salut Jobi Merci pour cela, j'ai mis à jour la question pour être plus clair. Je ne veux pas que cette solution dépende de la VM pour fonctionner. –

+2

Le ViewModel ne doit jamais déterminer la façon dont les données sont présentées. –

+1

C'est un peu impropre car tout le point d'une VM est de déterminer comment les données sont présentées. Les booléens représentant la visibilité, les enums représentant les états, cela se produit tout le temps. –

3

Je suis resté coincé sur le même problème récemment. J'ai finalement décidé que les propriétés attachées sont la voie à suivre, et a fini avec une fonctionnalité qui fonctionne un peu comme ceci:

<Grid x:Name="LayoutRoot" Background="White"> 
    <ListBox x:Name="ListItems"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Border> 
        <Border.Style> 
         <Style TargetType="Border"> 
          <Setter Property="Background" Value="White" /> 
         </Style> 
        </Border.Style> 
        <local:ItemsControlAlternation.AlternateStyle> 
         <Style TargetType="Border"> 
          <Setter Property="Background" Value="LightBlue" /> 
         </Style> 
        </local:ItemsControlAlternation.AlternateStyle> 
        <ContentPresenter Content="{Binding}" /> 
       </Border> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

Je posté à ce sujet ici: http://www.philsversion.com/2010/11/22/alternating-row-styles-in-silverlight/

Phil

P.S. Désolé pour l'auto-promotion flagrante :)

Questions connexes