Question

J'aimerais que plusieurs zones de texte réagissent aux modifications d'une chaîne sous-jacente. Donc, si je changeais le contenu de la chaîne, tous ces champs de texte changeraient aussi leur contenu.

Maintenant, je ne peux pas utiliser le type String pour cela car il est immuable. Alors je suis allé avec StringBuilder. Mais la propriété Text d'un objet TextBox ne prend que String.

Existe-t-il un moyen facile de "lier" & l'objet StringBuilder à la propriété Text d'un TextBox?

Merci beaucoup!

PS: La TextBox est actuellement WPF. Mais je pourrais passer à Windows Forms à cause de Mono.

Était-ce utile?

La solution

Vous pouvez toujours exposer une propriété dont la fonction getter renvoie le ToString () du constructeur de chaînes. Le formulaire pourrait alors se lier à cette propriété.

private StringBuilder _myStringBuilder;

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

Autres conseils

Il semble que ma réponse précédente n’était pas très bien formulée, car beaucoup de personnes ont mal compris ce que j’allais dire et je vais donc essayer à nouveau de prendre en compte leurs commentaires.

Le fait qu'un objet String soit immuable ne signifie pas qu'une variable de type String ne peut pas être modifiée. Si un objet a une propriété de type String, l'affectation d'un nouvel objet String à cette propriété entraîne la modification de la propriété (dans ma réponse initiale, je l'appelais la variable en mutation, apparemment certaines personnes ne sont pas d'accord avec l'utilisation du terme " ; muter "dans ce contexte).

Le système de liaison de données WPF peut être lié à cette propriété. S'il est informé que la propriété change via INotifyPropertyChanged, il mettra à jour la cible de la liaison, permettant ainsi à plusieurs zones de texte de se lier à la même propriété et toutes les modifications lors d'une mise à jour de la propriété sans nécessiter de code supplémentaire.

Par conséquent, il n'est pas nécessaire d'utiliser StringBuilder comme magasin de sauvegarde pour la propriété. A la place, vous pouvez utiliser une propriété String standard et implémenter 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 peut s'y connecter et prendra automatiquement en compte les modifications apportées à la valeur de la propriété . Non, l'objet String n'a pas muté, mais la propriété String a mutée (ou modifiée, si vous préférez).

Voici ce que j'utilise pour lier StringBuilder à TextBox dans 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


}

Dans ViewModel:

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

Dans Xaml:

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

Bien sûr, vous pouvez exposer d'autres méthodes StringBuilder si vous en avez besoin.

Vous pouvez hériter de la zone de texte et remplacer la propriété Text pour récupérer et écrire dans le générateur de chaînes.

En termes simples, non. La propriété de texte ne prend qu'une chaîne. Ainsi, quelle que soit la source, vous devrez le convertir en chaîne.

Pour vous permettre de le définir facilement une fois pour plusieurs zones de texte, vous pouvez avoir une propriété de classe qui définit toujours toutes les valeurs de zone de texte ...

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

Je placerais le StringBuilder dans une classe personnalisée avec une méthode Add , une méthode Text et un OnChanged événement.

Câblez la méthode Add de sorte que, lorsqu'elle est appelée, elle ajoute le texte à l'occurrence StringBuilder et déclenche l'événement. Ensuite, lorsque l'événement se déclenche, utilisez la méthode Text pour créer un ToString sur 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(); }
   }
}

Vous pouvez lier la propriété Text d'un TextBox à une propriété string ... L'objet String est immuable, mais une variable de type String est parfaitement mutable ...

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

Cependant, vous devez le placer dans un objet qui implémente INotifyPropertyChanged.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top