Search code examples
c#wpfxamldatagrid

How to bind List<string> and display its collection into a DataGridTemplateColumn


I'm trying to display a list of string items on a column in my DataGrid. But if I just bind the List object what it displays is the text (Collection). Every other data in my DataGrid comes up fine, except for this column. I would like for it to display the contents of said collection.

In my ViewModel I have:

 /// <summary>
/// The list I'm binding to the Itemsource
/// </summary>
public ObservableCollection<Foo> FooCollection
{
    get
    {
        return _fooCollection;
    }
    set
    {
        if(_fooCollection != value)
        {
            _fooCollection  = value;
            RaisePropertyChanged(nameof(FooCollection));
        }
    }
}
private ObservableCollection<Foo> _fooCollection = new ObservableCollection<Foo>();

public MyViewModel()
{
    FooCollection = _myServices.GetFooCollection();
}

In my XAML I have:

 <DataGrid
            ItemsSource="{Binding FooCollection, Mode=OneWay}"
            VerticalScrollBarVisibility="Auto"
            AutoGenerateColumns="False"
            HorizontalAlignment="Left"
            VerticalAlignment="Stretch"
            BorderThickness="3"
                  Margin="10,10,10,17"
            CanUserAddRows="False"
            CanUserDeleteRows="False"                 
            Grid.Row="2"
            SelectionMode="Single"
            IsReadOnly="True" >
     <DataGrid.Columns>
     <!--Other column definitions-->
     <DataGridTextColumn
                    Header="Places"
                    Binding="{Binding Places}">
                </DataGridTextColumn>
     </DataGrid.Columns>
</DataGrid>

In my DataModel I have:

public class Foo:
{
        /// <summary>
        /// Roles
        /// </summary>
        public List<string> Places { get; set; }

        //... Constructors

        //... Methods
}

Solution

  • You can use a value converter, e.g.:

    public class ListToStringConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value!= null && value is List<string> lstStr)
            {
                return string.Join(",", lstStr);
            }
            return value?.GetType().ToString();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("One way converter!");
        }
    }
    

    XAML:

    <DataGrid ...>
        <DataGrid.Resources>
            <local:ListToStringConverter x:Key="lstToString"/>
        </DataGrid.Resources>
         <DataGridTextColumn
                        Header="Places"
                        Binding="{Binding Places, Converter="{StaticResource lstToString}"}">
                    </DataGridTextColumn>
         </DataGrid.Columns>
    </DataGrid>