2009-09-07 29 views

Trả lời

18

tôi sử dụng này cho C# winforms, nên dễ dàng điều chỉnh để 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); 
    } 
} 

Sử dụng nó như

TraceListener debugListener = new MyTraceListener (theTextBox); 
Debug.Listeners.Add(debugListener); 
Trace.Listeners.Add(debugListener); 

Hãy nhớ theo dõi/gỡ lỗi.Listeners.Remove (debugListener); khi bạn không cần nó nữa.

+0

+1 cho BeginInvoke(). Regular Invoke() treo toàn bộ ứng dụng. – sharkin

+0

Bạn có nghĩa là 'mới * My * TraceListener (theTextBox) ' –

+0

tương đương' wpf 'là gì –

0

bạn có thể nối thêm Trình xử lý tùy chỉnh cập nhật thuộc tính Textbox.Text. Do đó, bạn cần kế thừa từ lớp cơ sở trừu tượng TraceListener và ghi đè lên một trong các phương thức TraaceData, TraceEvent, TraceTransfer.

11

Làm thế nào về việc triển khai TraceListener tùy chỉnh chỉ đơn giản gắn thêm thông điệp dấu vết vào chuỗi? Sau đó, bạn phơi bày chuỗi đó dưới dạng thuộc tính, triển khai INotifyPropertyChanged và databind điều khiển TextBox cho thuộc tính đó.

Something như thế này:

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); 
     } 
    } 
} 

Bạn sẽ cần phải thêm TraceListener này vào danh sách các người nghe tích cực:

Trace.Listeners.Add(new MyTraceListener()); 
+0

Cảm ơn bạn, có vẻ như đó là một ý tưởng rất hay. Tôi sẽ đánh giá cao một số hướng dẫn. – kjv

+1

Chỉ cần nhớ rằng phương pháp này không phải là chủ đề an toàn - không móc nó lên đến điều khiển gui nếu bạn đang đăng nhập từ các chủ đề khác hơn là thread gui – nos

+0

@ nos: Điểm tốt. Tôi để nó như một bài tập cho người đọc :) –

2

Mã dưới đây là phong cách C# 6.0 của mã @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); 
    } 
} 

Giả sử rằng MainViewModel là gốc DataContext của tệp MainWindow.xaml. Để áp dụng MyTraceListener theo cách MVVM, hãy viết mã bên dưới trong 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. 
    } 
} 

Trong MainWindow.xaml, bind TraceOutput thuộc tính vào TextBox. Nếu bạn muốn TextBox cuộn xuống dưới cùng với nhật ký tích lũy, hãy áp dụng sự kiện TextChanged.

<TextBox x:Name="TextBoxLog" TextWrapping="Wrap" Text="{Binding TraceOutput}" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" TextChanged="TextBoxLog_OnTextChanged" /> 

trong mã phía sau tệp XAML (MainWindow.xaml.cs), trình xử lý sự kiện đơn giản như dưới đây.

private void TextBoxLog_OnTextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBoxLog.ScrollToEnd(); 
    } 
Các vấn đề liên quan