0

I'm creating a logger application thing to learn WPF, and I want new messages to appear at the bottom of a scrollviewer every time some listener picks up a new message. I want each message to create something that looks like this:

================================== = Source | Message = = | = = | = ================================== 

I've got 2 WPF books here, and they both have "warnings" saying that there are other simpler and better mechanisms than custom/user controls in most cases. I was wondering if this can be solved using control templates, and if so, what control type should I use as a base?

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This is what I'll end up doing.
0

Try using using a ListView and setting its View to a GridView.

<ListView> <ListView.View> <GridView> <GridViewColumn Header="Source" Width="120" /> <GridViewColumn Header="Message" Width="400" /> </GridView> </ListView.View> </ListView> 

Refer: How to: Display ListView Contents by Using a GridView

4 Comments

I'll give it a try and credit you for your answer if nothing more suitable turns up. I'm so new to WPF that I can't confirm if this is the best solution :)
If you want to display Source and Message in a tabular format (and each new message is supposed to be a new line item), probably this is the simplest way. However, if you want it to work more like a 'tail', and want to keep only the latest (say 10) messages, then either: A. you need to shuffle items in above solution (not good idea, or B. you need to look for alternatives.
Okay. I'll credit you with the answer since it would have been a good solution to the problem the way I presented it. I'll be choosing alternative B though because of other issues ;)
So, is it that you need to keep the latest (say 10) messages? In that case, you can still use the ListView and bind it to sample code that Captain Garforce has mentioned below. Should work for you. And if performance is imporatant, you may use a queue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.