Pregunta

Me gustaría que varios cuadros de texto reaccionen a los cambios de una cadena subyacente. Entonces, si tuviera que cambiar el contenido de la cadena, todos esos cuadros de texto también cambiarían su contenido.

Ahora, no puedo usar el tipo String para eso ya que es inmutable. Así que fui con StringBuilder. Pero la propiedad Text de un objeto TextBox solo toma String.

¿Hay una forma fácil de " enlazar " el objeto StringBuilder a la propiedad Text de un TextBox?

¡Muchas gracias!

PS: El TextBox es actualmente WPF. Pero podría cambiar a Windows Forms debido a Mono.

¿Fue útil?

Solución

Siempre se podría exponer una propiedad que el getter devuelve el ToString () del Stringbuilder. El formulario podría vincularse a esta propiedad.

private StringBuilder _myStringBuilder;

public string MyText
{
  get { return _myStringBuilder.ToString(); }
}

Otros consejos

Parece que mi respuesta anterior no estaba muy bien redactada, ya que muchas personas entendieron mal el punto que estaba haciendo, así que intentaré nuevamente teniendo en cuenta los comentarios de las personas.

El hecho de que un objeto String sea inmutable no significa que una variable de tipo String no se pueda cambiar. Si un objeto tiene una propiedad de tipo String, al asignar un nuevo objeto String a esa propiedad se cambia la propiedad (en mi respuesta original, me referí a esto como la variable que muta, aparentemente algunas personas no están de acuerdo con el uso del término " ; mutar " en este contexto).

El sistema de enlace de datos WPF puede enlazar a esta propiedad. Si se notifica que la propiedad cambia a través de INotifyPropertyChanged, se actualizará el objetivo del enlace, permitiendo así que muchos cuadros de texto se unan a la misma propiedad y todos los cambios en una actualización de la propiedad sin requerir ningún código adicional.

Por lo tanto, no es necesario utilizar StringBuilder como almacén de respaldo para la propiedad. En su lugar, puede usar una propiedad de cadena estándar 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 puede vincularse a esto y automáticamente recogerá y los cambios realizados en el valor de la propiedad . No, el objeto String no ha mutado, pero la propiedad String ha mutado (o cambiado, si lo prefiere).

Aquí, lo que uso para enlazar StringBuilder a TextBox en 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


}

En ViewModel:

public BindableStringBuilder ErrorMessages { get; set; }
ErrorMessages.AppendLine("Missing Image: " + imagePath);

En Xaml:

<TextBox Text="{Binding ErrorMessages.Text, Mode=OneWay}"/>

Por supuesto, puede exponer otros métodos de StringBuilder si lo necesita.

Podría heredar el cuadro de texto y anular la propiedad de Texto para recuperar y escribir en el generador de cadenas.

En pocas palabras, no. La propiedad de texto solo toma una cadena. Entonces, cualquiera que sea la fuente, tendrás que convertirla en una Cadena.

Para permitirte configurarla fácilmente una vez para muchos cuadros de texto, puedes tener una propiedad de clase que siempre establece todos los valores de cuadro de texto ...

public string MyString
{
  get
  {
   ///... 
  }
  set 
  {
    textbox1.Text = value;
    textbox2.Text = value;
    //...
  }
}

Envolvería el StringBuilder en una clase personalizada con el método Add , el método Text y un OnChanged evento.

Conecte el método Add de tal manera que cuando se lo llama, agrega el texto a la instancia de StringBuilder y dispara el evento. Luego, cuando se dispare el evento, use el método Text para hacer un ToString en el 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(); }
   }
}

Puede enlazar la propiedad de Texto de un Cuadro de Texto a una propiedad de cadena ... El objeto de Cadena es inmutable, pero una variable de tipo Cadena es perfectamente mutable ...

string mutable = "I can be changed";
mutable = "see?";

Sin embargo, deberías envolverlo en un objeto que implementa INotifyPropertyChanged.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top