Perhaps Binding can help. (It might overcomplicate things if you're still learning WPF though.)
With binding we can make the ListView only be the visible representation of your logging, meaning the logic to add/remove logs can stay separate from the ListView entirely.
class LogEntry { public string Source { get; set; } public string Message { get; set; } public LogEntry(string source, string message) { Source = source; Message = message; } } class Listener { private int m_maxLogs = 10; private ObservableCollection<LogEntry> m_logEntries; public ObservableCollection<LogEntry> LogEntries { get { return m_logEntries; } } public Listener() { m_logEntries = new ObservableCollection<LogEntry>(); } public void AddLogEntry(string source, string message) { if (LogEntries.Count >= m_maxLogs) { //Remove the oldest LogEntry. LogEntries.RemoveAt(0); } LogEntries.Add(new LogEntry(source, message)); } }
If the datacontext is set to the Listener instance the xaml becomes (based on the previous answer):
<ListView ItemsSource="{Binding LogEntries}"> <ListView.View> <GridView> <GridViewColumn Header="Source" Width="120" DisplayMemberBinding="{Binding Source}"/> <GridViewColumn Header="Message" Width="400" DisplayMemberBinding="{Binding Message}"/> </GridView> </ListView.View> </ListView>
If you want to dynamically change the text of your log entries for some reason, you'll need to implement the INotifyPropertyChanged interface in the LogEntry class to make the listview update.