Nor*_*ren 2 .net c# data-binding winforms
技术:.NET 4,C#,WinForms,Visual Studio 2010
我正在处理学习数据绑定,甚至无法得到一个简单的例子来按预期工作.我有一个带有我绑定标签的表单,显示当前鼠标光标坐标.
public partial class Form1 : Form, INotifyPropertyChanged
{
[Bindable(true)]
private String cursorPosition;
public String CursorPosition
{
get
{
return cursorPosition;
}
set
{
cursorPosition = value;
NotifyPropertyChanged("CursorPosition");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Form1()
{
InitializeComponent();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
CursorPosition = "(" + Convert.ToString(e.X) + " , " + Convert.ToString(e.Y) + ")";
}
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
从设计器开始,我设置了标签的Data Binding,将Text属性绑定到form1BindingSource - CursorPosition.我错过了什么?
编辑:更新的代码段.
从设计器开始,我设置了标签的Data Binding,将Text属性绑定到form1BindingSource - CursorPosition.我错过了什么?
你有没有设置:
form1BindingSource.DataSource = this; // (or whatever the real data source is)
Run Code Online (Sandbox Code Playgroud)
例如在表单的构造函数中,之后InitializeComponent?
(这假设您的Form1实例是数据源,并且您通过a将控件绑定到它BindingSource.)
一些进一步的细节建议:
选择表单本身作为数据源有点不寻常.恕我直言,最好将所有绑定属性分离为单独的非UI数据对象.然后,您可以为INotifyPropertyChanged实现创建可重用的基本类型.
正如@rfmodulator在他的回答中所说,BindableAttribute附属于该领域:
[Bindable(true)]
private String cursorPosition;
public String CursorPosition
…
Run Code Online (Sandbox Code Playgroud)
您可能想将它附加到该属性:
private String cursorPosition;
[Bindable(true)]
public String CursorPosition
…
Run Code Online (Sandbox Code Playgroud)你的二传手应该看起来像这样:
set
{
if (!string.Equals(cursorPosition, value) // +
{ // +
cursorPosition = value;
NotifyPropertyChanged("CursorPosition");
} // +
}
Run Code Online (Sandbox Code Playgroud)
也就是说,仅PropertyChanged在属性值实际更改时引发事件.
您可能希望将NotifyPropertyChanged方法更改为:
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged; // +
if (handler != null) // ~
{
handler(this, new PropertyChangedEventArgs(propertyName)); // ~
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为理论上PropertyChanged可以在null检查和调用之间进行更改.您可以通过创建事件委托的本地副本来排除这种理论上的可能性.
PS:为了准确,因为杰弗里里希特指出了"通过C#CLR"他的书,一个局部变量还是不太够:理想情况下,你会分配Interlocked.CompareExchange(ref PropertyChanged, null, null)到handler(而不是简单PropertyChanged),因为使用该方法将防止JIT代码发电机优化掉局部变量(IIRC).