Как использовать ItemsControl с WrapPanel для вывода списка элементов через запятую? - PullRequest
3 голосов
/ 08 июля 2011

У меня есть ItemsControl, который перечисляет элементы, разделяя их запятой. Код следующий:

<ItemsControl ItemsSource="{Binding MyItems}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text=", " 
                           Name="commaTextBlock"/>
                <TextBlock Text="{Binding}"/>
            </StackPanel>
            <!-- Hide the first comma -->
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding 
                        RelativeSource={RelativeSource PreviousData}}" 
                             Value="{x:Null}">
                    <Setter Property="Visibility" 
                            TargetName="commaTextBlock" 
                            Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Результат примерно такой: Item1, Item2, Item3

Теперь я хотел бы сделать то же самое, используя WrapPanel вместо StackPanel в качестве ItemsPanelTemplate. Я проверил это, и он отлично работает, за исключением небольшой детали, он делает что-то вроде этого:

Item1, Item2

, Item3

Конечно, это потому, что запятая стоит перед каждым элементом, а я скрываю первый. Я хотел бы поставить запятую после каждого элемента и скрыть последний, поэтому результат будет следующим:

Item1, Item2,

Item3

Было бы очень просто, если бы существовало что-то вроде NextData (так что я бы привязался к этому, а не к PreviousData), но, к сожалению, такого не существует (или я его не нашел). У кого-нибудь есть идеи, как решить эту проблему?

Спасибо

Ответы [ 2 ]

4 голосов
/ 08 июля 2011

Я сделал преобразователь видимости для аналогичной проблемы:

<TextBlock Text=", " Name="commaTextBlock"> 
   <TextBlock.Visibility>
       <MultiBinding Converter="{StaticResource commaVisibilityConverter}">
       <Binding ElementName="myItemsControl" Path="ItemsSource"/>
       <Binding/>
    </MultiBinding>                            
   </TextBlock.Visibility>
</TextBlock>

И преобразователь логика:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var collection = values[0] as IEnumerable<MyItem>;
        var item = values[1] as MyItem;
        if ((collection != null) && (item != null) && (collection.Count() > 0))
        {
            return collection.Last() == item ? Visibility.Hidden : Visibility.Visible;
        }          

        return Visibility.Hidden;
    }
3 голосов
/ 08 июля 2011

Может быть, вы можете попробовать использовать мультисвязывание и конвертер.Примерно так:

<ItemsControl.ItemTemplate>
  <DataTemplate>
    <TextBlock>
      <TextBlock.Text>
        <MultiBinding Converter="{StaticResource myConverter}">
          <Binding Mode="OneWay"/>
          <Binding ElementName="root" Path="ItemsSource" Mode="OneWay"/>
        </MultiBinding>
      </TextBlock.Text>
    </TextBlock>
  </DataTemplate>
</ItemsControl.ItemTemplate>

Где root - имя вашего ItemsControl.

И написать конвертер, который проверяет положение:

public class MyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var text = values[0] as string;
        var list = values[1] as ObservableCollection<string>;

        //check for null etc...

        if (list.IndexOf(text) == list.Count - 1)
            return text;

        return string.Format("{0}, ", text);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
       //ignore this, not gonna happen with OneWay Binding 
       return null;
    }
}

Работает длямне!Надеюсь, это поможет вам в вашей проблеме!

РЕДАКТИРОВАТЬ :
Почти так же, как и в другом ответе, разница здесь в том, что вам нужен только 1 TextBlock в вашем шаблонеконвертер решает, есть ли запятая или нет.Но в принципе тот же принцип.MultiBinding скалы!: -)

...