Como ligar TextBox controle para uma instância de StringBuilder?
-
03-07-2019 - |
Pergunta
Gostaria várias caixas de texto para reagir às mudanças de uma cadeia subjacente. Então, se eu fosse para mudar o conteúdo da seqüência, todas aquelas caixas de texto mudaria seu conteúdo também.
Agora, eu não posso usar o tipo String para que, uma vez que é imutável. Então eu fui com StringBuilder. Mas a propriedade de texto de um objeto TextBox só leva cadeia.
Existe uma maneira fácil de "ligar" o objeto StringBuilder para a propriedade Text de um TextBox?
Muito obrigado!
PS: A caixa de texto é atualmente WPF. Mas eu poderia mudar para o Windows Forms por causa de Mono.
Solução
Você sempre pode expor uma propriedade que de getter retorna o ToString () do StringBuilder. O formulário pode então ligar-se a essa propriedade.
private StringBuilder _myStringBuilder;
public string MyText
{
get { return _myStringBuilder.ToString(); }
}
Outras dicas
Parece que minha resposta anterior não foi formulada muito bem, como muitas pessoas mal entendido o ponto que eu estava fazendo, por isso vou tentar novamente tomando em conta as observações das pessoas.
Só porque um objeto String é imutável, não significa que uma variável do tipo String não pode ser alterado. Se um objeto tem uma propriedade do tipo String, em seguida, atribuir um novo objeto String para que a propriedade faz com que a propriedade para a mudança (na minha resposta original, me referi a isso como a variável mutação, aparentemente, algumas pessoas não concordam com o uso do termo " mutação" neste contexto).
O sistema de ligação de dados do WPF pode vincular a essa propriedade. Se for notificado de que a propriedade muda através INotifyPropertyChanged, em seguida, ele irá atualizar o alvo da ligação, permitindo assim que muitas caixas de texto para vincular a mesma propriedade e toda a mudança em uma atualização da propriedade sem necessidade de qualquer código adicional.
Portanto, não há necessidade de usar StringBuilder como o armazenamento de backup para a propriedade. Em vez disso, você pode usar uma propriedade String padrão e implementar 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 pode ligar-se a isso e vai automaticamente pegar e alterações feitas no valor do propriedade . Não, o objeto String não sofreu uma mutação, mas a propriedade String tem mutante (ou alterado, se você preferir).
Aqui o que eu uso para StringBuilder se ligam a TextBox no WPF:
public class BindableStringBuilder : INotifyPropertyChanged
{
private readonly StringBuilder _builder = new StringBuilder();
private EventHandler<EventArgs> TextChanged;
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<T>(Expression<Func<T>> 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
}
Em ViewModel:
public BindableStringBuilder ErrorMessages { get; set; }
ErrorMessages.AppendLine("Missing Image: " + imagePath);
Em XAML:
<TextBox Text="{Binding ErrorMessages.Text, Mode=OneWay}"/>
Claro que você pode expor outros métodos StringBuilder se você precisar.
Você poderia herdar a caixa de texto e substituir a propriedade de texto para recuperar e gravação para o construtor string.
Em termos simples, não. propriedade de texto só leva uma String. Portanto, qualquer que seja a fonte, você vai ter que convertê-lo em um String.
Para que você possa configurá-lo facilmente uma vez que para muitas caixas de texto, você pode ter uma propriedade de classe que sempre define todos os valores da caixa de texto ...
public string MyString
{
get
{
///...
}
set
{
textbox1.Text = value;
textbox2.Text = value;
//...
}
}
Eu envolveria o StringBuilder
em uma classe personalizada com um método Add
, método Text
, e um evento OnChanged
.
Fio-se o método Add
tal que quando é chamado, acrescenta o texto para a instância StringBuilder
e aciona o evento. Então, quando o evento é acionado, use o método Text
para fazer um ToString
na StringBuilder
.
public class StringBuilderWrapper
{
private StringBuilder _builder = new StringBuilder();
private EventHandler<EventArgs> TextChanged;
public void Add(string text)
{
_builder.Append(text);
if (TextChanged != null)
TextChanged(this, null);
}
public string Text
{
get { return _builder.ToString(); }
}
}
Você pode vincular a propriedade Text de uma caixa de texto para uma propriedade string ... O objeto String é imutável, mas uma variável do tipo String é perfeitamente mutável ...
string mutable = "I can be changed";
mutable = "see?";
Você precisa envolvê-lo em um objeto que implementa INotifyPropertyChanged, no entanto.