【发布时间】:2010-11-26 05:34:14
【问题描述】:
对于我的 WPF 应用程序,我使用 TextWriterTraceListener 将日志记录到文本文件。如何将 Trace 输出也显示到文本框?
【问题讨论】:
标签: c# wpf textbox trace listener
对于我的 WPF 应用程序,我使用 TextWriterTraceListener 将日志记录到文本文件。如何将 Trace 输出也显示到文本框?
【问题讨论】:
标签: c# wpf textbox trace listener
我将它用于 C# winforms,应该可以轻松调整为 wpf
public class MyTraceListener : TraceListener
{
private TextBoxBase output;
public MyTraceListener(TextBoxBase output) {
this.Name = "Trace";
this.output = output;
}
public override void Write(string message) {
Action append = delegate() {
output.AppendText(string.Format("[{0}] ", DateTime.Now.ToString()));
output.AppendText(message);
};
if (output.InvokeRequired) {
output.BeginInvoke(append);
} else {
append();
}
}
public override void WriteLine(string message) {
Write(message + Environment.NewLine);
}
}
像这样使用它
TraceListener debugListener = new MyTraceListener (theTextBox);
Debug.Listeners.Add(debugListener);
Trace.Listeners.Add(debugListener);
记得 Trace/Debug.Listeners.Remove(debugListener);当你不再需要它时。
【讨论】:
new *My*TraceListener(theTextBox)
wpf equivalent 是什么
如何实现一个自定义 TraceListener,它只是将跟踪消息附加到一个字符串?然后将该字符串公开为属性,实现 INotifyPropertyChanged 并将 TextBox 控件数据绑定到该属性。
类似这样的:
public class MyTraceListener : TraceListener, INotifyPropertyChanged
{
private readonly StringBuilder builder;
public MyTraceListener()
{
this.builder = new StringBuilder();
}
public string Trace
{
get { return this.builder.ToString(); }
}
public override void Write(string message)
{
this.builder.Append(message);
this.OnPropertyChanged(new PropertyChangedEventArgs("Trace"));
}
public override void WriteLine(string message)
{
this.builder.AppendLine(message);
this.OnPropertyChanged(new PropertyChangedEventArgs("Trace"));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
}
您需要将此 TraceListener 添加到活动侦听器列表中:
Trace.Listeners.Add(new MyTraceListener());
【讨论】:
下面的代码是@Mark Seemann 的C#6.0 风格的代码。
public class MyTraceListener : TraceListener, INotifyPropertyChanged
{
private readonly StringBuilder _builder;
public MyTraceListener()
{
_builder = new StringBuilder();
}
public string Trace => _builder.ToString();
public override void Write(string message)
{
_builder.Append(message);
OnPropertyChanged(new PropertyChangedEventArgs("Trace"));
}
public override void WriteLine(string message)
{
_builder.AppendLine(message);
OnPropertyChanged(new PropertyChangedEventArgs("Trace"));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
}
假设 MainViewModel 是 MainWindow.xaml 文件的根 DataContext。要以 MVVM 方式应用 MyTraceListener,请在 MainViewModel.cs 中编写以下代码。
private string _traceOutput;
private readonly MyTraceListener _trace = new MyTraceListener();
// Constructor
public MainViewModel() {
// ...your viewmodel initialization code.
// Add event handler in order to expose logs to MainViewModel.TraceOutput property.
WeakEventManager<INotifyPropertyChanged, PropertyChangedEventArgs>.AddHandler(_trace, "PropertyChanged", traceOnPropertyChanged);
Trace.Listeners.Add(_trace);
}
private void traceOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Trace")
TraceOutput = _trace.Trace;
}
public string TraceOutput
{
get { return _traceOutput; }
set {
_traceOutput = value;
RaisePropertyChanged(); // This method is from Mvvm-light.
}
}
在 MainWindow.xaml 中,将 TraceOutput 属性绑定到 TextBox。如果您希望 TextBox 连同累积的日志一起滚动到底部,请应用 TextChanged 事件。
<TextBox x:Name="TextBoxLog" TextWrapping="Wrap" Text="{Binding TraceOutput}" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" TextChanged="TextBoxLog_OnTextChanged" />
在 XAML 文件 (MainWindow.xaml.cs) 的代码隐藏中,事件处理程序如下所示。
private void TextBoxLog_OnTextChanged(object sender, TextChangedEventArgs e)
{
TextBoxLog.ScrollToEnd();
}
【讨论】:
您可以附加一个自定义侦听器来更新 Textbox.Text 属性。 因此,您需要从抽象基类 TraceListener 继承并覆盖 TraaceData、TraceEvent、TraceTransfer 方法之一。
【讨论】: