0

I am trying to bind name with comma-separated values. In the last item I don't want to add a comma. Can you please let me know how to remove the last comma in WinRT application?

<ItemsControl ItemsSource="{Binding xxxx}" >
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"></StackPanel>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal" Margin="0,-6,0,0" >    
                                        <HyperlinkButton x:Name="name" Content="{Binding Name}" VerticalAlignment="Top" Style="{ThemeResource TileContentHyperlinkStyle}"  ></HyperlinkButton>
                                        <TextBlock x:Name="Comma" x:Uid="/Resources/Comma" Style="{ThemeResource TileContentStyle}" VerticalAlignment="Center" Margin="0,0,5,0" />
                                    </StackPanel>
                             </DataTemplate>
                            </ItemsControl.ItemTemplate>  

Example output:

Ramesh ,Sutha,Nikhil, <=== (need to remove last comma)

  • Use an IValueConverter to format your data for display. https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.data.ivalueconverter?f=255&MSPPError=-2147217396 – Ken Tucker Jan 10 '16 at 19:37

1 Answers1

1

You can add a flag in your view model to detect whether to show the comma. For example:

In MyViewModel, add a IsLast property as the flag:

public class MyViewModel
{
    public string Name { get; set; }

    public bool IsLast { get; set; } = false;
}

Then in XAML, bind the Visibility property of TextBlock to IsLast:

<ItemsControl ItemsSource="{Binding }">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="0,-6,0,0" Orientation="Horizontal">
                <HyperlinkButton x:Name="suspectname"
                                 VerticalAlignment="Top"
                                 Content="{Binding Name}"
                                 Style="{ThemeResource IncidentSmallTileContentHyperlinkStyle}" />
                <TextBlock x:Uid="/Resources/Comma"
                           x:Name="Comma"
                           Margin="0,0,5,0"
                           VerticalAlignment="Center"
                           Style="{ThemeResource IncidentSmallTileContentStyle}"
                           Visibility="{Binding IsLast,
                                                Converter={StaticResource MyVisibilityConverter}}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Here we need a Converter to convert bool to Visibility:

public class MyVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var isLast = (bool)value;
        if (isLast)
        {
            return Visibility.Collapsed;
        }
        else
        {
            return Visibility.Visible;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

After this, we can add some data to have a test:

public MainPage()
{
    this.InitializeComponent();

    List<MyViewModel> MyList = new List<MyViewModel>() {
        new MyViewModel() { Name = "Ramesh" },
        new MyViewModel() { Name = "Sutha" },
        new MyViewModel() { Name = "Nikhil", IsLast = true }
    };
    this.DataContext = MyList;
}

Update:

Adding a flag for comma in the viewmodel is not a good approach. Using a data template selector to switch between a template with and without the comma may be a better way.

To do this, we need two templates first, the template for the first item should have no comma and the others need a comma:

<DataTemplate x:Key="CommonDataTemplate">
    <StackPanel Margin="0,-6,0,0" Orientation="Horizontal">
        <TextBlock x:Name="Comma"
                   Margin="0,0,5,0"
                   VerticalAlignment="Center"
                   Text="," />
        <HyperlinkButton x:Name="suspectname"
                         VerticalAlignment="Top"
                         Content="{Binding Name}" />
    </StackPanel>
</DataTemplate>
<DataTemplate x:Key="FirstDataTemplate">
    <StackPanel Margin="0,-6,0,0" Orientation="Horizontal">
        <HyperlinkButton x:Name="suspectname"
                         VerticalAlignment="Top"
                         Content="{Binding Name}" />
    </StackPanel>
</DataTemplate> 

Then we need to create a data template selector class which inherits from DataTemplateSelector class and override the SelectTemplateCore method to implement the logic. In the method, we can use ItemsControl.ItemsControlFromItemContainer method to get the ItemsControl and ItemsControl.IndexFromContainer method to get the index of the container then detect whether the item is the first item of the ItemsControl by comparing the index:

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate CommonTemplate { get; set; }
    public DataTemplate FirstTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
        if (itemsControl.IndexFromContainer(container) == 0)
        {
            return FirstTemplate;
        }
        return CommonTemplate;

    }
}

After this we can add MyTemplateSelector in Page.Resources like following:

<local:MyTemplateSelector x:Key="MyTemplateSelector"
                          CommonTemplate="{StaticResource CommonDataTemplate}"
                          FirstTemplate="{StaticResource FirstDataTemplate}" />

Then we can use it in ItemsControl:

<ItemsControl ItemTemplateSelector="{StaticResource MyTemplateSelector}" ItemsSource="{Binding }">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
Jay Zuo
  • 15,653
  • 2
  • 25
  • 49
  • Thanks jay ... I have followed same ..its working for now – Suthahar Jegatheesan JS Jan 12 '16 at 16:24
  • @SuthaharJ: Adding a flag for comma in the viewmodel is not a good approach. I updated my answer and use a data template selector to switch between a template with and without the comma. With this approach, we do not need to change the viewmodel, you can have a check. – Jay Zuo Jan 13 '16 at 11:42