2012-11-29 32 views
2

发生了什么事是它不打印/绑定/发布到WPF表单文本框中的视图如果字符串是相同的。例如,如果我使用随机生成的字节数组,我将它作为一个字符串,然后它发布到视图。为什么AppendText依赖项属性在字符串相等时不打印?

这里是我的视图模型,视图,势必:

public class ViewModel : INotifyPropertyChanged 
    { 
     public StringBuilder Data 
     { 
     get { return _data; } 
     set 
     { 
      _data = value; 
      OnPropertyChanged("Data"); 
     } 
     } 

     private Service service = new Service(); 
     private StringBuilder _data; 

     public ViewModel() 
     { 
     service.BytesArrived += ServiceOnBytesArrived; 
     ThreadPool.QueueUserWorkItem(starupService); 
     } 

     private void starupService(object state) 
     { 
     service.Start(); 
     } 

     private void ServiceOnBytesArrived(byte[] bytes) 
     { 
     var sBuilder = new StringBuilder(); 
     foreach (var b in bytes) 
     { 
      sBuilder.Append(b.ToString() + ", "); 
     } 

     Data = sBuilder; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

这里的,如果随意使用而不是仅仅是印刷字节对我来说(服务工作正常:

public class Service 
    { 
     public void Start() 
     { 
     var random = new Random(DateTime.Now.Minute); 

     while (true) 
     { 
     //random.NextBytes(bytes); 
     for (int i = 0; i < 10; i++) 
     { 
      bytes[i] = 0; 
      Thread.Sleep(10); 
     } 
     //Thread.Sleep(100); 
     BytesArrived(bytes); 
     } 
    } 

    private byte[] bytes = new byte[10]; 
    public event Action<byte[]> BytesArrived; 
} 

这里的依赖属性使用AppendText,我正在使用:

public static class TextBoxAttachedBehaviors 
    { 
     #region AppendText Attached Property 

     public static string GetAppendText(TextBox textBox) 
     { 
     return (string)textBox.GetValue(AppendTextProperty); 
     } 

     public static void SetAppendText(
     TextBox textBox, string value) 
     { 
     textBox.SetValue(AppendTextProperty, value); 
     } 

     public static readonly DependencyProperty AppendTextProperty = 
     DependencyProperty.RegisterAttached(
      "AppendText", 
      typeof(string), 
      typeof(TextBoxAttachedBehaviors), 
      new UIPropertyMetadata(null, OnAppendTextChanged)); 

     private static void OnAppendTextChanged(DependencyObject d, 
               DependencyPropertyChangedEventArgs e) 
     { 
     if (e.NewValue == null) 
      return; 
     TextBox textBox = d as TextBox; 
     textBox.AppendText(e.NewValue.ToString()); 
     } 

     #endregion 
    } 

该XAML:

<TextBox attachedBehaviors:TextBoxAttachedBehaviors.AppendText="{Binding TextBoxAppend}"/> 

如果您有ReSharper,它将提供替换命名空间,例如, attachedBehaviors:与实际附加行为的链接,在我的情况下是xmlns:attachedBehaviors="clr-namespace:Support.NetworkMonitor.AttachedBehaviors"

+1

你可以在你设置AppendText的地方添加代码吗? –

+0

@Sten Petrov我已经更新了包含XAML的答案。 – Contango

回答

1

DependencyProperties在它们发出通知之前比较它们的旧值和新值,并且只有在确实存在差异时才会触发它。解决办法很简单:不久设置AppendText通过为null您设置的字符串之前,像

public StringBuilder Data 
    { 
    get { return _data; } 
    set 
    { 
     _data = null; 
     OnPropertyChanged("Data"); 
     _data = value; 
     OnPropertyChanged("Data"); 
    } 
    } 
+0

尝试在最后一行之前添加textBox.AppendText(null),并尝试执行textBox.SetValue(AppendTextProperty,null);上面一行textBox.SetValue(AppendTextProperty,value);既没有工作。 –

+0

我添加了一些代码... – hbarck

+0

仍然是相同的结果。 –

0

我发现这个从我写了一个工作的应用程序...也许这会有所帮助。

Public Class TextBoxLog 
    Inherits Freezable 
    Implements WPFGlue.Framework.IStickyComponent 

    Private _AppendTextDelegate As Action(Of String) 
    Private _ScrollToEndDelegate As Action 
    Private _ResetDelegate As Action 

    Public Shared ReadOnly LogProperty As DependencyProperty = DependencyProperty.RegisterAttached("Log", GetType(TextBoxLog), GetType(TextBoxLog), New PropertyMetadata(AddressOf WPFGlue.Framework.StickyComponentManager.OnStickyComponentChanged)) 
    Public Shared Function GetLog(ByVal d As DependencyObject) As TextBoxLog 
     Return d.GetValue(LogProperty) 
    End Function 
    Public Shared Sub SetLog(ByVal d As DependencyObject, ByVal value As TextBoxLog) 
     d.SetValue(LogProperty, value) 
    End Sub 


    Public Shared ReadOnly LogMessageProperty As DependencyProperty = DependencyProperty.Register("LogMessage", GetType(String), GetType(TextBoxLog), New PropertyMetadata(AddressOf OnLogMessageChanged)) 
    Public Property LogMessage As String 
     Get 
      Return GetValue(LogMessageProperty) 
     End Get 
     Set(ByVal value As String) 
      SetValue(LogMessageProperty, value) 
     End Set 
    End Property 
    Private Shared Sub OnLogMessageChanged(ByVal d As TextBoxLog, ByVal e As DependencyPropertyChangedEventArgs) 
     If e.NewValue IsNot Nothing Then 
      d.WriteLine(e.NewValue) 
     End If 
    End Sub 

    Protected Overridable Sub Attach(base As Object) 
     If Not TypeOf base Is System.Windows.Controls.Primitives.TextBoxBase Then 
      Throw New ArgumentException("Can only be attached to elements of type TextBoxBase") 
     End If 
     Dim tb As System.Windows.Controls.Primitives.TextBoxBase = base 
     _AppendTextDelegate = AddressOf tb.AppendText 
     _ScrollToEndDelegate = AddressOf tb.ScrollToEnd 
     _ResetDelegate = AddressOf Me.Reset 
    End Sub 

    Protected Overridable Sub Detach(ByVal base As Object) 
     _AppendTextDelegate = Nothing 
     _ScrollToEndDelegate = Nothing 
     _ResetDelegate = Nothing 
    End Sub 

    Private Sub Reset() 
     SetCurrentValue(LogMessageProperty, Nothing) 
    End Sub 

    Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable 
     Return New TextBoxLog 
    End Function 

    Public Overridable Sub Write(message As String) 
     If _AppendTextDelegate IsNot Nothing Then 
      _AppendTextDelegate.Invoke(message) 
      _ScrollToEndDelegate.Invoke() 
      '    Me.Dispatcher.Invoke(_ResetDelegate, Windows.Threading.DispatcherPriority.Background) 
     End If 
    End Sub 

    Public Overridable Sub WriteLine(message As String) 
     If _AppendTextDelegate IsNot Nothing Then 
      _AppendTextDelegate.Invoke(message) 
      _AppendTextDelegate.Invoke(vbNewLine) 
      _ScrollToEndDelegate.Invoke() 
      '    Me.Dispatcher.Invoke(_ResetDelegate, Windows.Threading.DispatcherPriority.Background) 
     End If 
    End Sub 

    Public ReadOnly Property Mode As Framework.AttachMode Implements Framework.IStickyComponent.Mode 
     Get 
      Return Framework.AttachMode.Immediate 
     End Get 
    End Property 

    Public Sub OnAttach(base As Object, e As System.EventArgs) Implements Framework.IStickyComponent.OnAttach 
     If e Is System.EventArgs.Empty Then 
      Attach(base) 
     End If 
    End Sub 

    Public Sub OnDetach(base As Object, e As System.EventArgs) Implements Framework.IStickyComponent.OnDetach 
     If e Is System.EventArgs.Empty Then 
      Detach(base) 
     End If 
    End Sub 
End Class 

对于这篇文章的目的,你可以假设的是,当登录连接属性设置OnAttach被调用,OnDetach当它没有设置,或卸载。

相关问题