Alexander
Alexander

Reputation: 1061

Data-Binding: Display a list of strings

I have got a class called Track:

public class Track
{
    public string Title { get; set; }      
    public List<Artist> Artists { get; set; }

}

This class contains a list of Artist objects:

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

Now I want to bind this to a GridView in WPF:

 <ListView x:Name="TracksList" Margin="37,325,33,0" VerticalAlignment="Top" Grid.ColumnSpan="1" MouseDoubleClick="TrackList_MouseDoubleClick" Foreground="#FFDEDEDE" Background="#FF232323">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Title}" Width="400px" Header="Titel" />
                    <GridViewColumn DisplayMemberBinding="{Binding Artists}" Width="200px" Header="Artists" />     
                </GridView> 
            </ListView.View>
        </ListView>

I use the a List of Track objects to fill this GridView:

TracksList.ItemsSource = album.TrackCollection;

What I want to achieve is to display a string containg all the artist names in the Artists column (e.g. "Artist 1, Artist 2, Artist 3"). What I get is a string explaining that this field contains a list. I do understand why I get this result: I did not tell the binding how to resolve and display the list.

How can I configure the binding so that a list of the artists is displayed in the column fields.

Upvotes: 0

Views: 430

Answers (3)

Dennis
Dennis

Reputation: 37760

That's why there are view models:

public class TrackViewModel
{
    public TrackViewModel(Track model)
    {
        Title = model.Title;
        Artists = string.Join(", ", model.Artists.Select(a => a.Name));
    }

    public string Title { get; private set; }
    public string Artists { get; private set; }
}

Upvotes: 1

Clemens
Clemens

Reputation: 128013

You may use a Binding.Converter like this:

class ArtistsListConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        object result = null;
        var artists = value as IEnumerable<Artist>;

        if (artists != null)
        {
            result = string.Join(", ", artists.Select(a => a.Name));
        }

        return result;
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

XAML:

<local:ArtistsListConverter x:Key="ArtistsListConverter"/>
...
DisplayMemberBinding="{Binding Artists,
                       Converter={StaticResource ArtistsListConverter}}" 

Upvotes: 2

VijayKP
VijayKP

Reputation: 321

If you bind the List of Artist the converter is actually getting that only. So, this is the slightly improvised version of Converter.

public class ArtistsToStringConverter : System.Windows.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var artists = value as IEnumerable<Artist>;

        if (artists != null)
        {
            var artistNames = from artist in artists select artist.Name;
            return string.Join(", ", artistNames);
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 1

Related Questions