c# - 简单绑定(bind) .NET 数据绑定(bind)不起作用

标签 c# .net winforms data-binding

技术:.NET 4、C#、WinForms、Visual Studio 2010

我正在学习数据绑定(bind),甚至连一个简单的示例都无法按预期工作。我有一个带有我绑定(bind)到的标签的表单,该标签显示当前鼠标光标坐标。

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

从设计师那里,我已经设置标签的数据绑定(bind)以将 Text 属性绑定(bind)到 form1BindingSource - CursorPosition。我错过了什么?

编辑:更新了代码片段。

最佳答案

From the designer, I have set the label's Data Binding to bind the Text property to form1BindingSource - CursorPosition. What am I missing?

你设置了吗:

form1BindingSource.DataSource = this;  // (or whatever the real data source is)

例如在窗体的构造函数中,在 InitializeComponent 之后?

(假设您的 Form1 实例是数据源,并且您通过 BindingSource 将控件绑定(bind)到它。)


一些更详细的建议:

  1. 选择表单本身作为数据源有些不寻常。恕我直言,最好将所有绑定(bind)到的属性分离到一个单独的非 UI 数据对象中。然后,您可以为 INotifyPropertyChanged 实现创建可重用的基类型。

  2. 正如@rfmodulator 在他的回答中所说,BindableAttribute 附加到该字段:

    [Bindable(true)]
    private String cursorPosition;
    public String CursorPosition
    …
    

    您可能打算将其附加到属性:

    private String cursorPosition;
    [Bindable(true)]
    public String CursorPosition
    …
    
  3. 您的setter 应该看起来像这样:

    set
    {
        if (!string.Equals(cursorPosition, value)      // +
        {                                              // +
            cursorPosition = value;
            NotifyPropertyChanged("CursorPosition");
        }                                              // +
    }
    

    也就是说,仅在属性值实际更改时引发 PropertyChanged 事件。

  4. 您可能希望将您的 NotifyPropertyChanged 方法更改为:

    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;          // +
        if (handler != null)                                            // ~
        {
            handler(this, new PropertyChangedEventArgs(propertyName));  // ~
        }
    }
    

    这是因为 PropertyChanged 理论上可以在 null 检查和调用之间改变。您可以通过创建事件委托(delegate)的本地副本来排除这种理论上的可能性。

    P.S.:准确地说,正如 Jeffrey Richter 在他的“CLR via C#”一书中指出的那样,局部变量仍然不够:理想情况下,您可以分配 Interlocked.CompareExchange(ref PropertyChanged , null, null)handler(而不是简单的 PropertyChanged),因为使用该方法将阻止 JIT 代码生成器优化局部变量 (IIRC) .

关于c# - 简单绑定(bind) .NET 数据绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9402679/

相关文章:

c# - Lambda 表达式创建不相关的编译错误

C# - 字节数组 - byte[] - 有简单的比较器吗?

c# - 无法加载文件或程序集 'System.Web.Http.Owin'

c# - 如何获取系统的玻璃颜色?

c# - Winforms 本地化错误

c# - 手动处理 WinForms 控件的滚动

c# - 我应该在哪里过滤微服务架构模式中的 MS 级外部服务响应?

c# - 每n秒唤醒一次线程

.net - 用于开始 .NET 紧凑型框架开发的硬件

c# - 编程字符串的表单资源使用情况?