В моем приложении WPF я записываю в текстовый файл с помощью TextWriterTraceListener. Как я могу также отобразить вывод трассировки в текстовое поле?
Слушатель трассировки для записи в текстовое поле (приложение WPF)
Ответ 1
Я использую это для 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);
Не забудьте отслеживать /Debug.Listeners.Remove(debugListener); когда вам это больше не нужно.
Ответ 2
Как реализовать пользовательский 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());
Ответ 3
Ниже приведен код С# 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.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();
}
Ответ 4
вы можете добавить пользовательский Listener, который обновляет свойство Textbox.Text. Поэтому вам необходимо наследовать от абстрактного базового класса TraceListener и переопределить один из методов TraaceData, TraceEvent, TraceTransfer.