web-dev-qa-db-ja.com

ラベルを「変数」にバインドする

Xという名前のグローバル変数INTがあるとします。Xはグローバルであるため、値はいつでも変更できるように、何でもその値を変更できると想定できます。

「label」という名前のLabelコントロールがあるとします。これが私が達成したいことです:

Label.Textの値を変数Xに「バインド」したいのですが、変数Xが変更されると、値がlabel.Textに反映されます。

ここで、イベントリスナーを作成して、このリスナーでデリゲートを操作したくありません(できるだけ少ない量のコードが必要です)。これにDataBindingコンポーネントを使用する方法はありますか?または他の新しい技術?

25
Ian

Databindingインフラストラクチャを使用して、値に加えられた変更を反映する場合は、バインディング値に加えられた変更について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
}

最初にラベルのバインディングを設定する必要があることも覚えておいてください:

public frmFoo()
{
    InitializeComponent();
    lblTest.DataBindings.Add(new Binding("Text", this, "Foo"));
}
32
Iñaki Elcoro

マルチスレッドプログラムの場合(ほとんどすべてのWindowsフォームプログラム)、iCeの答えは適切ではありません。とにかくラベルを変更できないためです(クロススレッドエラーが発生します)。問題を修正する最も簡単な方法は、セッターでプロパティを作成することです。

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

ここで、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;
     }
}
9

パブリック変数にバインドすることはできないと思います。変数自体には、その値の変更をリスナーに通知する機能はありません。

そのため、変数をプロパティにラップする必要があります。 setterでイベントを発生させ、それにバインドされているUIコントロールに通知して、新しい値を更新して表示できるようにします。フレームワークには、このためのメカニズムがあります-INotifyPropertyChanged-試してみてください ハウツーのこのリンク

3
Gishu

Xのプロパティを作成します。セッターでlabel.Textプロパティを更新します。

private int _x;
public int X {
    get 
    { 
        return _x; 
    } 
    set 
    { 
        _x = value;
        label.Text = _x.ToString();
    }
}
1
Krunal