I'm trying to programmatically bind data from a list to a GridView in WPF. It works perfectly, but I want to format a TimeSpan column to my needs, but when I use any StringFormat, the column just stays empty.
I have following (simplified) code:
foreach (var song in _manager.GetLibrarySongs())
{
LibraryView.Items.Add(song);
}
DataGridTextColumn durationColumn = new DataGridTextColumn
{
Header = "Duration",
Binding = new Binding("Duration") { StringFormat = "" }
};
LibraryView.Columns.Add(durationColumn);
Stringformat is empty here but whatever I put in there, it makes the column just empty. I tried "hh\:mm\:ss", "hh\:mm\\:ss", "{}{0:g}", ...
Does anyone know what I'm doing wrong? Thanks in advance!
Following code has been used in Visual Studio 2015 and have DataGrid with DateTime and TimeSpan columns with defined format.
For date following string is used "yyyy-MM-dd" while for time string "mm\:ss" is used (notice double back slash)
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
dataGrid = new DataGrid();
var stackPanel = new StackPanel { Orientation = Orientation.Vertical };
stackPanel.Children.Add(dataGrid);
Content = stackPanel;
Rnd = new Random();
Now = DateTime.Now;
Counter = 1;
foreach (var song in GetSongs())
dataGrid.Items.Add(song);
// var timeSpanConverter = new TimeSpanConverter();
var titleColumn = new DataGridTextColumn { Header = "Title", Binding = new Binding("Title") };
var authorColumn = new DataGridTextColumn { Header = "Author", Binding = new Binding("Author") };
var albumColumn = new DataGridTextColumn { Header = "Album", Binding = new Binding("Album")};
// var durationColumn = new DataGridTextColumn {Header = "Duration", Binding = new Binding("Duration") { Converter = timeSpanConverter } };
var durationColumn = new DataGridTextColumn { Header = "Duration", Binding = new Binding("Duration") { StringFormat = "mm\\:ss" } };
var releaseColumn = new DataGridTextColumn { Header = "Release", Binding = new Binding("Release") { StringFormat = "yyyy-MM-dd" } };
dataGrid.Columns.Add(titleColumn);
dataGrid.Columns.Add(authorColumn);
dataGrid.Columns.Add(albumColumn);
dataGrid.Columns.Add(durationColumn);
dataGrid.Columns.Add(releaseColumn);
}
private DataGrid dataGrid;
private int? Counter;
private DateTime? Now;
private Random Rnd;
private TimeSpan GetDuration() { return TimeSpan.FromSeconds(30 + Rnd.Next(500)); }
private DateTime GetRelease() { Counter += 1; return Now.Value.AddMilliseconds(Counter.Value); }
private string GetTitle() { return $"Title {Counter}"; }
private string GetAlbum() { return $"Album {Counter}"; }
private string GetAuthor() { return $"Author {Counter}"; }
private IList<Song> GetSongs()
{
var list = new List<Song>();
for(var i = 0; i < 1000; i++)
list.Add(new Song() {
Title = GetTitle(),
Album = GetAlbum(),
Author = GetAuthor(),
Release = GetRelease(),
Duration = GetDuration()
});
return list;
}
}
public class Song {
public string Title { get; set; }
public string Author { get; set; }
public string Album { get; set; }
public DateTime Release { get; set; }
public TimeSpan Duration { get; set; }
}
public class TimeSpanConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return ((TimeSpan)value).ToString("mm\\:ss");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
In case if approach with StringFormat is not working (which should not be the case) you can try approach with Converter (commented in code for Duration column)