carlsb3rg
carlsb3rg

Reputation: 772

When to use Custom/User Control or Template/Style

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?

Upvotes: 0

Views: 232

Answers (2)

Captain Garforce
Captain Garforce

Reputation: 608

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.

Upvotes: 1

publicgk
publicgk

Reputation: 3191

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

Upvotes: 0

Related Questions