Utiliser un modèle différent pour le dernier élément dans un contrôle des éléments du FPF

j'utilise un modèle personnalisé dans mon itemscontrol pour afficher le résultat suivant:

item 1, item 2, item3,

je veux changer le modèle du dernier élément de sorte que le résultat devient:

item 1, item2, item3

ItemsControl:

<ItemsControl ItemsSource="{Binding Path=MyCollection}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}"/>
                <TextBlock Text=", "/>
            </StackPanel>

        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>
<!-Y a-t-il quelqu'un qui puisse trouver une solution à mon problème? Je vous remercie!

18
demandé sur MarqueIV 2011-10-14 15:41:31

4 réponses

j'ai trouvé la solution pour mon problème en utilisant seulement XAML. Si il y a quelqu'un qui doit faire de même, utiliser ceci:

<ItemsControl ItemsSource="{Binding Path=MyCollection}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            <StackPanel Orientation="Horizontal">
                <TextBlock x:Name="comma" Text=", "/>
                <TextBlock Text="{Binding}"/>
            </StackPanel>

            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
                    <Setter TargetName="comma" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>

        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>
49
répondu Bram W. 2017-03-04 17:55:42

Vous pouvez utiliser DataTemplateSelector, en Selectttemplate () méthode vous pouvez vérifier si l'élément est le dernier et ensuite retourner un autre modèle.

In XAML:

<ItemsControl.ItemTemplate>     
  <DataTemplate>
      <ContentPresenter 
             ContentTemplateSelector = "{StaticResource MyTemplateSelector}">

Dans le Code behind:

 private sealed class MyTemplateSelector: DataTemplateSelector
 { 

    public override DataTemplate SelectTemplate(
                                      object item, 
                                      DependencyObject container)
    {
        // ...
    }
  }
7
répondu sll 2011-10-14 11:50:18

Cette solution affecte la dernière ligne et mises à jour avec les changements de la collection sous-jacente:


Code

le convertisseur a besoin de 3 paramètres pour fonctionner correctement - l'item courant, l'itemscontrol, l'itemscount, et renvoie true si l'item courant est aussi le dernier item:

  class LastItemConverter : IMultiValueConverter
    {

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int count = (int)values[2];

            if (values != null && values.Length == 3 && count>0)
            {
                System.Windows.Controls.ItemsControl itemsControl = values[0] as System.Windows.Controls.ItemsControl;
                var itemContext = (values[1] as System.Windows.Controls.ContentPresenter).DataContext;

                var lastItem = itemsControl.Items[count-1];

                return Equals(lastItem, itemContext);
            }

            return DependencyProperty.UnsetValue;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

XAML

le déclencheur de données d'un DataTemplate, qui inclut une zone de texte nommée "PART_TextBox":

  <DataTemplate.Triggers>
            <DataTrigger Value="True" >
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource LastItemConverter}">
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" />
                        <Binding RelativeSource="{RelativeSource Self}"/>
                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="Items.Count"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Foreground" TargetName="PART_TextBox" Value="Red" />
            </DataTrigger>
 </DataTemplate.Triggers>      

Le convertisseur comme une ressource statique dans le code Xaml

<Window.Resources>
     <local:LastItemConverter x:Key="LastItemConverter" />
</Window.Resources>

Instantané

Et un cliché d'elle en action

enter image description here le code a été ajouté au itemscontrol de ce 'codeprojet' https://www.codeproject.com/Articles/242628/A-Simple-Cross-Button-for-WPF

Remarque: le dernier article du texte en rouge

1
répondu Declan Taylor 2017-08-28 20:46:43

une question... Je vois que vous êtes en utilisant un ItemsControl plutôt que de dire un ListBox et qu'il semble être lié à une collection de chaînes, et que vous essayez seulement d'afficher le texte résultant sans formater les différentes parties, ce qui me fait me demander si votre sortie désirée est en fait la chaîne elle-même comme mentionné dans la question, et pas un ItemsControl en soi.

si j'ai raison à ce sujet, avez-vous envisagé d'utiliser un simple TextBlock liés aux articles la collecte, mais alimentée par un convertisseur? Puis à l'intérieur du convertisseur, vous couleriez value à un tableau de cordes, puis dans le Convert méthode, tout simplement Join eux en utilisant une virgule comme séparateur qui les ajoutera automatiquement entre les éléments, comme ainsi...

var strings = (IEnumerable<String>)value;

return String.Join(", ", strings);
0
répondu MarqueIV 2017-03-04 18:07:22