8

基になる文字列の変更に反応するいくつかのテキスト ボックスが必要です。したがって、文字列の内容を変更すると、それらすべてのテキスト ボックスの内容も変更されます。

現在、文字列型は不変であるため使用できません。だから私はStringBuilderに行きました。ただし、TextBox オブジェクトの Text プロパティは文字列しか取りません。

StringBuilder オブジェクトを TextBox の Text プロパティに「バインド」する簡単な方法はありますか?

どうもありがとう!

PS: TextBox は現在 WPF です。しかし、Mono のために Windows Forms に切り替えるかもしれません。

4

7 に答える 7

11

getterがStringbuilderのToString()を返すプロパティをいつでも公開できます。その後、フォームはこのプロパティにバインドできます。

private StringBuilder _myStringBuilder;

public string MyText
{
  get { return _myStringBuilder.ToString(); }
}
于 2009-01-05T16:33:03.883 に答える
10

ここで、WPF で StringBuilder を TextBox にバインドするために使用するもの:

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


}

ViewModel で:

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

Xaml の場合:

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

もちろん、必要に応じて他の StringBuilder メソッドを公開することもできます。

于 2015-09-09T16:37:16.400 に答える
9

前回の回答は言葉足らずで、私の指摘を誤解されている方が多かったようです。

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 プロパティ変更されています (または必要に応じて変更されています)。

于 2009-01-06T10:12:45.553 に答える
1

簡単に言えば、違います。テキストプロパティは文字列のみを取ります。したがって、ソースが何であれ、それを文字列に変換する必要があります。

多くのテキストボックスに一度簡単に設定できるようにするために、常にすべてのテキストボックス値を設定するクラスプロパティを設定できます...

public string MyString
{
  get
  {
   ///... 
  }
  set 
  {
    textbox1.Text = value;
    textbox2.Text = value;
    //...
  }
}
于 2009-01-05T16:34:36.423 に答える
1

テキスト ボックスを継承し、Text プロパティをオーバーライドして、取得して文字列ビルダーに書き込むことができます。

于 2009-01-05T16:32:10.453 に答える
0

メソッド、メソッド、およびイベントStringBuilderを使用してカスタム クラスにラップします。AddTextOnChanged

メソッドが呼び出されたときにテキストがインスタンスAddに追加され、イベントが発生するように、メソッドを接続します。StringBuilder次に、イベントが発生Textしたら、 メソッドを使用して に対して a を実行しToStringます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(); }
   }
}
于 2009-01-05T22:21:37.597 に答える
-5

TextBoxのTextプロパティをstringプロパティにバインドできます...Stringオブジェクトは不変ですが、String型の変数は完全に変更可能です...

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

ただし、INotifyPropertyChangedを実装するオブジェクトでラップする必要があります。

于 2009-01-05T16:33:39.843 に答える