Прослушиватель трассировки для записи в текстовое поле (приложение WPF)
для моего приложения WPF я делаю вход в текстовый файл с помощью TextWriterTraceListener. Как я могу также отобразить вывод трассировки в текстовое поле?
4 ответов
Я использую это для 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);
Не забудьте отследить/отладить.Слушатели.Удалите (debugListener); когда вам это больше не нужно.
Как насчет реализации пользовательского 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());
ниже кода находится стиль C#6.0 кода @Mark Seemann.
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 является root DataContext
в MainWindow.файл XAML. Применить MyTraceListener
в манере MVVM напишите ниже код в MainViewModel.цезий.
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, bind TraceOutput
свойство в текстовое поле. Если вы хотите, чтобы текстовое поле прокручивалось вниз вместе с накопленными журналами, примените 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();
}
вы можете добавить пользовательский прослушиватель, который обновляет текстовое поле.Свойство text. Поэтому необходимо наследовать от абстрактного базового класса TraceListener и переопределить один из методов TraaceData, TraceEvent, TraceTransfer.