Für meine WPF-Anwendung protokollieren ich eine Textdatei mit einem TextWriterTraceListener. Wie kann ich die Ausgabe von Trace auch in einem Textfeld anzeigen?Trace-Listener zum Schreiben in ein Textfeld (WPF-Anwendung)
Antwort
Ich benutze dies für C# WinForms, sollte leicht verstellbar sein
wpfpublic 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);
}
}
Verwenden sie es wie
TraceListener debugListener = new MyTraceListener (theTextBox);
Debug.Listeners.Add(debugListener);
Trace.Listeners.Add(debugListener);
Remember zu Trace/Debug.Listeners.Remove (debugListener); wenn du es nicht mehr brauchst.
können Sie einen benutzerdefinierten Listener anhängen, der die Textbox.Text-Eigenschaft aktualisiert. Sie müssen daher von der abstrakten Basisklasse TraceListener übernehmen und eine der Methoden TraaceData, TraceEvent, TraceTransfer überschreiben.
Wie wäre es, einen benutzerdefinierten TraceListener zu implementieren, der Trace-Nachrichten einfach an eine Zeichenfolge anhängt? Sie geben dann diese Zeichenfolge als eine Eigenschaft frei, implementieren INotifyPropertyChanged und binden ein TextBox-Steuerelement an diese Eigenschaft.
Etwas wie folgt aus:
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);
}
}
}
Sie müssten diese Tracelistener in die Liste der aktiven Zuhörer hinzuzufügen:
Trace.Listeners.Add(new MyTraceListener());
Vielen Dank, es scheint wie eine sehr gute Idee. Ich würde eine Anleitung schätzen. – kjv
Denken Sie daran, dass dieser Ansatz nicht threadsicher ist - verbinden Sie ihn nicht mit GUI-Steuerelementen, wenn Sie von anderen Threads als dem GUI-Thread protokollieren – nos
@nos: Guter Punkt. Ich überlasse das als Übung für den Leser :) –
Der folgende Code ist C# 6.0-Stil von @Mark Seemanns Code.
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);
}
}
sei angenommen, dass MainViewModel Stammdatei DataContext
von MainWindow.xaml ist. Um MyTraceListener
in MVVM-Art anzuwenden, schreiben Sie den folgenden Code in 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.
}
}
In MainWindow.xaml binden TraceOutput
Eigenschaft auf TextBox. Wenn Sie möchten, dass die TextBox zusammen mit angesammelten Protokollen nach unten blättert, wenden Sie das Ereignis TextChanged
an.
<TextBox x:Name="TextBoxLog" TextWrapping="Wrap" Text="{Binding TraceOutput}" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" TextChanged="TextBoxLog_OnTextChanged" />
in Code-Behind der XAML-Datei (MainWindow.xaml.cs), ist Event-Handler einfach wie unten.
private void TextBoxLog_OnTextChanged(object sender, TextChangedEventArgs e)
{
TextBoxLog.ScrollToEnd();
}
- 1. C# - Schreiben in ein mehrzeiliges Textfeld
- 2. C# - Ein Protokoll mit einem Textfeld schreiben
- 3. TraceListener in OWIN Self-Hosting
- 4. tracelistener zu web.config hinzufügen
- 5. Wie benutzerdefinierte TraceListener in app.config definieren
- 6. Ein benutzerdefiniertes Attribut zum Festlegen, ob ein Textfeld editierbar ist
- 7. QWidgets in ein Textfeld setzen
- 8. C# Ausgabe in ein Textfeld
- 9. Mimicng caret in ein Textfeld
- 10. TraceListener zu allen TraceSources hinzufügen/entfernen
- 11. Wie ein Textfeld in Javascript
- 12. Application Insights TraceListener sammelt keine Spuren?
- 13. Ein Beispiel zum Schreiben eines NPAPI-Plugins in Linux?
- 14. Ein Makro zum Schreiben eines privaten Makros in ThisWorkBook
- 15. Wie ein Datum in ein Textfeld konvertieren
- 16. Platzieren Sie ein Bild in ein Textfeld
- 17. Abschluss eines benutzerdefinierten TraceListener mit autoflush = 'false' (C#, .net)
- 18. Wie ein Textfeld in vb.net füllen
- 19. CSS-Center ein Textfeld
- 20. Drucken nur ein Textfeld
- 21. Ein resizierbares Textfeld implementieren?
- 22. Testergebnis in MbUnit mit Gallio schreiben
- 23. Datagrid-Spaltenkopf mit einem Textfeld zum Filtern
- 24. Wie wichtige Ereignisse zu schreiben, wenn sich der Cursor in das Textfeld ein
- 25. Wie kann ich ein Textfeld in ein anderes Textfeld in HTML einbetten?
- 26. Webgl: Alternative zum Schreiben in gl_FragDepth
- 27. Verhindern, dass Benutzer Zeichen in ein Textfeld in SWT eingeben
- 28. Wie UITextField Cursor zum nächsten Textfeld verschieben
- 29. Welchen Pfad zum Schreiben in java -classpath?
- 30. NSCoding - Objekt zum Schreiben wiederverwenden?
+1 für BeginInvoke(). Regular Invoke() hängt die gesamte App. – sharkin
Sie meinen 'neu * Mein * TraceListener (theTextBox)' –
was ist das 'wpf Äquivalent' –