C# 如何将 TextBox 控件绑定到 StringBuilder 实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/413675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:28:09  来源:igfitidea点击:

Howto bind TextBox control to a StringBuilder instance?

c#.netstringtextboxstringbuilder

提问by user51710

I would like several textboxes to react to changes of an underlying string. So if I were to change the content of the string, all those textboxes would change their content too.

我想要几个文本框对底层字符串的变化做出反应。因此,如果我要更改字符串的内容,所有这些文本框也会更改其内容。

Now, I can't use the String type for that as it is immutable. So I went with StringBuilder. But the Text property of a TextBox object only takes String.

现在,我不能为此使用 String 类型,因为它是不可变的。所以我选择了 StringBuilder。但是 TextBox 对象的 Text 属性只接受 String。

Is there an easy way to "bind" the StringBuilder object to the Text property of a TextBox?

是否有一种简单的方法可以将 StringBuilder 对象“绑定”到 TextBox 的 Text 属性?

Many thanks!

非常感谢!

PS: The TextBox is currently WPF. But I might switch to Windows Forms because of Mono.

PS:TextBox 目前是 WPF。但我可能会因为 Mono 而切换到 Windows 窗体。

采纳答案by Ray Booysen

You could always expose a property that's getter returns the ToString() of the Stringbuilder. The form could then bind to this property.

你总是可以公开一个属性,它的 getter 返回 Stringbuilder 的 ToString()。然后表单可以绑定到这个属性。

private StringBuilder _myStringBuilder;

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

回答by Tom Anderson

You could inherit the text box and override the Text property to retrieve and write to the string builder.

您可以继承文本框并覆盖 Text 属性以检索并写入字符串生成器。

回答by Giraffe

You can bind the Text property of a TextBox to a string property... The String object is immutable, but a variable of type String is perfectly mutable...

您可以将 TextBox 的 Text 属性绑定到字符串属性... String 对象是不可变的,但 String 类型的变量是完全可变的...

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

You would need to wrap it up in an object that implements INotifyPropertyChanged, however.

但是,您需要将其包装在实现 INotifyPropertyChanged 的​​对象中。

回答by Kon

Simply put, no. Text property only takes a String. So whatever the source, you'll have to convert it to a String.

简单地说,没有。Text 属性只需要一个字符串。因此,无论来源如何,您都必须将其转换为字符串。

To enable you to easily set it once for many textboxes, you can have a class property that always sets all textbox values...

为了使您能够轻松地为多个文本框设置一次,您可以拥有一个始终设置所有文本框值的类属性...

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

回答by Chris Brandsma

I would wrap the StringBuilderin a custom class with an Addmethod, Textmethod, and an OnChangedevent.

我会StringBuilder用一个Add方法、Text方法和一个OnChanged事件将它包装在一个自定义类中。

Wire up the Addmethod such that when it is called it adds the text to the StringBuilderinstance and fires the event. Then when the event fires, use the Textmethod to do a ToStringon the StringBuilder.

连接Add方法,以便在调用它时将文本添加到StringBuilder实例并触发事件。然后,当事件触发,使用Text方法做ToStringStringBuilder

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(); }
   }
}

回答by Giraffe

It seems my previous answer wasn't worded very well, as many people misunderstood the point I was making, so I will try again taking into account people's comments.

看来我之前的回答不是很好,因为很多人误解了我的意思,所以我会考虑到人们的评论再试一次。

Just because a String object is immutable does not mean that a variable of type String cannot be changed. If an object has a property of type String, then assigning a new String object to that property causes the property to change (in my original answer, I referred to this as the variable mutating, apparently some people do not agree with using the term "mutate" in this context).

仅仅因为 String 对象是不可变的并不意味着不能更改 String 类型的变量。如果对象具有 String 类型的属性,则将新的 String 对象分配给该属性会导致该属性发生更改(在我的原始答案中,我将其称为变量变异,显然有些人不同意使用术语“变异”在这种情况下)。

The WPF databinding system can bind to this property. If it is notified that the property changes through INotifyPropertyChanged, then it will update the target of the binding, thus allowing many textboxes to bind to the same property and all change on an update of the property without requiring any additional code.

WPF 数据绑定系统可以绑定到此属性。如果通过 INotifyPropertyChanged 通知属性更改,则它将更新绑定的目标,从而允许许多文本框绑定到同一属性,并且所有更改都在属性更新时进行,而无需任何额外代码。

Therefore, there is no need to use StringBuilder as the backing store for the property. Instead, you can use a standard String property and implement INotifyPropertyChanged.

因此,不需要使用 StringBuilder 作为属性的后备存储。相反,您可以使用标准字符串属性并实现 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 can bind to this and will automatically pick up and changes made in the value of the property. No, the String object has not mutated, but the String property hasmutated (or changed, if you prefer).

WPF 可以绑定到 this 并且会自动选取和更改属性的值。不,String对象还没有变异,但String属性已经发生突变(或改变,如果你喜欢)。

回答by Saykor

Here what I use to bind StringBuilder to TextBox in WPF:

这是我用来在 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


}

In ViewModel:

在视图模型中:

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

In Xaml:

在 Xml 中:

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

Of course you can expose other StringBuilder methods if you need.

当然,如果需要,您可以公开其他 StringBuilder 方法。