views:

255

answers:

4

I'm needing to display a list of numbers from a collection in an Items Control. So the items are: "1", "2", "3".

When they are rendered, I need them separated by a comma (or something similar). So the above 3 items would look like this: "1, 2, 3".

How can I add a separator to the individual items, without having one tacked on the end of the list?

I am not stuck on using an ItemsControl, but that's what I had started to use.

+1  A: 

You could do something like this.

List<int> list = new List<int>() { 1, 2, 3 };
string items = string.Join(", ", list.Select(i => i.ToString()).ToArray());

That will transform a list of integers into a comma-seperated (plus a space) string. If the list of numbers are already stored as strings, then all you need to do is this.

List<string> list = new List<string>() { "1", "2", "3" };
string items = string.Join(", ", list.ToArray());

And, of course, if it's already an array of strings, forget the call to .ToArray()!

Anthony Pegram
A: 

I figured I should give the solution I ended up with.

I ended up binding my collection of items to the Text of a TextBlock, and using a value converter to change the bound collection of items into the formatted string.

Grandpappy
+3  A: 
<ItemsControl ItemsSource="{Binding Numbers}">
    <ItemsControl.ItemsPanel>
        <!-- could use a WrapPanel if more appropriate for your scenario -->
        <StackPanel Orientation="Horizontal"/>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock x:Name="commaTextBlock" Text=", "/>
            <TextBlock Text="{Binding .}"/>
        </DataTemplate>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
                <Setter Property="Visibility" TargetName="commaTextBlock" Value="Collapsed"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I arrived at your question because I was looking for a solution in Silverlight, which does not have a previous data relative source.

HTH,
Kent

Kent Boogaart
Very nice, I've been looking for a clean way to do this.
donovan
A: 

You can also multibind to ItemsControl.AlternationIndex and ItemsControl.Count and compare the AlternationIndex to Count to see if you are the last item.

Set the AlternationIndex high enough to accomodate all your items then make a LastItemConverter with a Convert method looking something like this:

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var alterationCount = (int)values[0];
        var itemCount = (int)values[1];
        if (itemCount > 1)
        {
            return alterationCount == (itemCount - 1) ? Visibility.Collapsed : Visibility.Visible;
        }

        return Visibility.Collapsed;
    }
Mo0gles