我想要几个文本框来对底层字符串的更改做出反应.因此,如果我要更改字符串的内容,所有这些文本框也会更改其内容.
现在,我不能使用String类型,因为它是不可变的.所以我选择了StringBuilder.但TextBox对象的Text属性只接受String.
有没有一种简单的方法将StringBuilder对象"绑定"到TextBox的Text属性?
非常感谢!
PS:TextBox目前是WPF.但是由于Mono,我可能会切换到Windows Forms.
看来我之前的回答措辞不是很好,因为很多人误解了我的观点,所以我会再次考虑人们的评论.
仅仅因为String对象是不可变的并不意味着不能更改String类型的变量.如果一个对象具有String类型的属性,那么为该属性分配一个新的String对象会导致该属性发生变化(在我的原始答案中,我将其称为变量变异,显然有些人不同意使用该术语"变异"在这种情况下".
WPF数据绑定系统可以绑定到此属性.如果通知INotifyPropertyChanged通知属性更改,那么它将更新绑定的目标,从而允许许多文本框绑定到同一属性,并且所有更改属性的更改都不需要任何其他代码.
因此,不需要使用StringBuilder作为属性的后备存储.相反,您可以使用标准String属性并实现INotifyPropertyChanged.
public class MyClass : INotifyPropertyChanged { private string myString; public string MyString { get { return myString; } set { myString = value; OnPropertyChanged("MyString"); } } protected void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion }
WPF可以绑定到此,并将自动获取和更改属性的值.不,String对象没有变异,但String属性已经变异(或者如果您愿意,可以更改).
你总是可以公开一个getter返回Stringbuilder的ToString()的属性.然后表单可以绑定到此属性.
private StringBuilder _myStringBuilder; public string MyText { get { return _myStringBuilder.ToString(); } }
这里我用来将StringBuilder绑定到WPF中的TextBox:
public class BindableStringBuilder : INotifyPropertyChanged { private readonly StringBuilder _builder = new StringBuilder(); private EventHandlerTextChanged; public string Text { get { return _builder.ToString(); } } public int Count { get { return _builder.Length; } } public void Append(string text) { _builder.Append(text); if (TextChanged != null) TextChanged(this, null); RaisePropertyChanged(() => Text); } public void AppendLine(string text) { _builder.AppendLine(text); if (TextChanged != null) TextChanged(this, null); RaisePropertyChanged(() => Text); } public void Clear() { _builder.Clear(); if (TextChanged != null) TextChanged(this, null); RaisePropertyChanged(() => Text); } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string property) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); } } public void RaisePropertyChanged (Expression > propertyExpression) { if (propertyExpression == null) { return; } var handler = PropertyChanged; if (handler != null) { var body = propertyExpression.Body as MemberExpression; if (body != null) handler(this, new PropertyChangedEventArgs(body.Member.Name)); } } #endregion }
在ViewModel中:
public BindableStringBuilder ErrorMessages { get; set; } ErrorMessages.AppendLine("Missing Image: " + imagePath);
在Xaml中:
当然,如果需要,您可以公开其他StringBuilder方法.