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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top