Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 何时使用自定义/用户控件或模板/样式_Wpf_User Controls - Fatal编程技术网

Wpf 何时使用自定义/用户控件或模板/样式

Wpf 何时使用自定义/用户控件或模板/样式,wpf,user-controls,Wpf,User Controls,我正在创建一个logger应用程序来学习WPF,我希望每次有侦听器接收到新消息时,新消息都会出现在scrollviewer的底部。我希望每条消息都能创建如下内容: ================================== = Source | Message = = | = = | = ============================

我正在创建一个logger应用程序来学习WPF,我希望每次有侦听器接收到新消息时,新消息都会出现在scrollviewer的底部。我希望每条消息都能创建如下内容:

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

我这里有两本WPF书籍,它们都有“警告”,说在大多数情况下,还有其他比自定义/用户控件更简单、更好的机制。我想知道是否可以使用控件模板解决这个问题,如果可以,我应该使用什么控件类型作为基础?

尝试使用
列表视图
并将其视图设置为
网格视图

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

请参阅:

绑定可能会有所帮助。(如果您仍在学习WPF,可能会使事情变得过于复杂。)
通过绑定,我们可以使
列表视图
仅成为日志的可见表示,这意味着添加/删除日志的逻辑可以与
列表视图
完全分离

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));
    }
}
类日志条目
{
公共字符串源{get;set;}
公共字符串消息{get;set;}
公共日志条目(字符串源、字符串消息)
{
来源=来源;
消息=消息;
}
}
类侦听器
{
私有int m_maxLogs=10;
私有可观察收集m_日志条目;
公共ObservableCollection日志项{get{return m_LogEntries;}}
公共侦听器()
{
m_logEntries=新的ObservableCollection();
}
public void AddLogEntry(字符串源、字符串消息)
{
如果(LogEntries.Count>=m_maxLogs)
{
//删除最旧的日志条目。
LogEntries.RemoveAt(0);
}
添加(新的日志条目(源、消息));
}
}
如果将datacontext设置为侦听器实例,xaml将变为(基于前面的回答):



如果出于某种原因希望动态更改日志项的文本,则需要在LogEntry类中实现
INotifyPropertyChanged
接口,以更新listview。

如果没有更合适的答案,我将尝试一下并相信您的答案。我对WPF是如此陌生,以至于我无法确认这是否是最好的解决方案:)如果您希望以表格格式显示源代码和消息(并且每个新消息都应该是一个新行项目),这可能是最简单的方法。但是,如果您希望它更像一个“尾巴”,并且只想保留最新(比如10条)的消息,那么:a.您需要在上述解决方案中洗牌项目(不是个好主意,或者B。你需要寻找替代方案。好的。我相信你的答案,因为这将是一个很好的解决问题的方法。尽管如此,我还是会选择替代方案B,因为其他问题;)那么,你是否需要保持最新(比如10)消息?在这种情况下,您仍然可以使用ListView并将其绑定到Garforce队长在下面提到的示例代码。应该适合您。如果性能很重要,您可以使用队列。这就是我最后要做的。
<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>