将标签绑定到"变量"

Ian*_*Ian 24 c# data-binding winforms

假设我有一个名为X的全局变量INT.由于X是全局的,我们可以假设任何东西都可以修改它的值,以便每次都更改它.

假设我有一个名为"label"的Label控件.这就是我想要完成的事情:

我想将label.Text的值"绑定"到变量X.这样,当变量X被更改时,它将被反射回label.Text.

现在,我不想编写事件监听器并与代理一起玩这个(我希望尽可能少的代码).有没有办法使用DataBinding组件?或任何其他新技术?

谢谢,伊恩

Iña*_*oro 32

如果要使用数据绑定基础结构并反映对值所做的更改,则需要一种方法来通知UI有关对绑定值所做的更改.

所以最好的方法是使用属性并实现INotifyPropertyChanged接口,如下所示:

class frmFoo : Form, INotifyPropertyChanged
{        
    private string _foo;

    public string Foo
    {
        get { return _foo; }
        set
        {
            _foo = value;
            OnPropertyChanged("Foo");
        }
    }

    protected virtual void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

还要记住,您需要首先在标签上设置绑定:

public frmFoo()
{
    InitializeComponent();
    lblTest.DataBindings.Add(new Binding("Text", this, "Foo"));
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案正是伊恩所需要的。也许在检查 null 之前创建 PropertyChanged 的​​副本会更好,否则它可能会在被调用之前立即更改为 null,如下所示: <code> protected virtual void OnPropertyChanged(string property) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(property)); } } </code>(详见http://stackoverflow.com/questions/672638/use-of-null-check-in-event-handler/672666#672666) (2认同)

Mac*_*bły 9

对于一个多线程程序(所以几乎每个windows窗体程序)iCe的答案都不是很好,因为它不会让你改变标签(你会得到一些交叉线程错误).解决问题的最简单方法是在setter中创建属性:

private string _labelText;
public string labelText
{
    get { return _labelText; }
    set
    {
        _labelText = value;
        updateLabelText(_labelText); //setting label to value
   }
}
Run Code Online (Sandbox Code Playgroud)

其中updateLabelText(string)是线程安全的:

delegate void updateLabelTextDelegate(string newText);
private void updateLabelText(string newText)
{
     if (label1.InvokeRequired)
     {
          // this is worker thread
          updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText);
          label1.Invoke(del, new object[] { newText });
     }
     else
     {
          // this is UI thread
          label1.Text = newText;
     }
}
Run Code Online (Sandbox Code Playgroud)