数据绑定到C#中的对象

时间:2009-04-03 19:30:34

标签: c# .net data-binding

Objective-c / cocoa提供了一种绑定形式,其中控件的属性(即文本框中的文本)可以绑定到对象的属性。我试图在C#w / .Net 3.5中复制此功能。

我在MyClass.cs文件中创建了以下非常简单的类:

class MyClass
{
    private string myName;

    public string MyName
    {
        get
        {
            return myName;
        }

        set
        {
            myName = value;
        }
    }

    public MyClass()
    {
        myName = "Allen";
    }
}

我还创建了一个带有1个文本框和1个按钮的简单表单。我在表单代码中初始化了一个Myclass实例并构建了项目。使用Vs2008中的DataSource向导,我选择了基于对象创建数据源,并选择了MyClass程序集。这创建了一个数据源实体。我将文本框的数据绑定更改为此数据源;但是,预期的结果(文本框的内容将是“allen”)未实现。此外,将文本放入文本框不会更新对象的name属性。

我知道我在这里缺少一些基本的东西。在某些时候,我应该将我在表单代码中初始化的MyClass类的实例绑定到文本框,但是没有发生。我在网上看到的一切似乎都掩盖了使用DataBinding和一个对象(或者我完全没有标记),所以任何帮助都非常感激。

编辑:

利用我从答案中学到的东西,我查看了Visual Studio生成的代码,它具有以下内容:

this.myClassBindingSource.DataSource = typeof(BindingTest.MyClass);

如果我发表评论并替换:

this.myClassBindingSource.DataSource = new MyClass();

我得到了预期的行为。为什么VS生成的默认代码是这样的?假设这比工作方法更正确,我应该如何修改我的代码才能在VS生成的范围内工作?

6 个答案:

答案 0 :(得分:15)

您必须将文本框的数据源指定为新的数据源。但另外,您必须将数据源的数据源分配为您的类的实例。

MyDataSource.DataSource = new MyClass();
TextBox1.DataSource = MyDataSource;

这应该适用于你的第一次传球。正如其他人所提到的,如果您要通过任何后台进程修改类属性,则可能需要在类上实现其他接口(INotifyPropertyChanged等)。

如果您只是通过表单更新属性,则不需要此步骤。

答案 1 :(得分:12)

您应该将Myotlass类型的INotifyPropertyChanged接口实现:

public class MyClass : INotifyPropertyChanged
{
   private string _myName;

   public string MyName
   {
       get { return _myName; }
       set
       {
          if( _myName != value )
          {
              _myName = value;
              OnPropertyChanged("MyName");
          }
       }
   }

   public event PropertyChangedEventHandler PropertyChanged;

   private void OnPropertyChanged(string propertyName)
   {
       if( PropertyChanged != null )
           PropertyChanged( this , new PropertyChangedEventArgs(propertyName) );
   }       
}

如果要支持简单数据绑定,则此接口是DataBinding基础结构所必需的。 INotifyPropertyChanged接口用于通知“绑定”属性已更改,因此DataBinding基础结构可以相应地执行操作。

然后,您可以将MyName属性数据绑定到文本框的Text属性。

答案 2 :(得分:3)

  

我在DataBinding.Add("TEXT", myObject, myObjectProperty)方法

中收到错误消息

这可能是因为你错过了属性声明中的显式{get; set;}!

坏:

public string FirstName;    //<-- you will not be able to bind to this property!

GOOD:

public string FirstName { get; set; }

答案 3 :(得分:0)

看起来您可能需要MyName属性上的Bindable属性(并遵循Frederik的建议):

   [System.ComponentModel.Bindable(true)] 
   public string MyName
   {
       get { return _myName; }
       set
       {
          if( _myName != value )
          {
              _myName = value;
              OnPropertyChanged("MyName");
          }
       }
   }

通过:http://support.microsoft.com/kb/327413

答案 4 :(得分:0)

我面前没有任何代码,但我认为数据源有点像集合。您必须将MyClass的实例添加到数据源,这就是表单字段将绑定到的内容。还有一些方法可以将数据源导航到MyClass的多个实例,但听起来并不像你需要的那样。检查DataSource的文档。

我认为你不需要实现任何花哨的界面。我似乎记得数据源上有一个方法,可以在更改某些值后刷新或重新绑定当前项。

答案 5 :(得分:0)

using System.Collections.Generic;

public class SiteDataItem
{ 
private string _text; 
private string _url; 
private int _id; 
private int _parentId;

public string Text
{  
    get 
    { 
        return _text; 
    }  
    set 
    { 
        _text = value;
    } 
}

public string Url 
{  
    get 
    { 
        return _url; 
    }  
    set 
    { 
        _url = value;
    } 
}
public int ID 
{  
    get 
    { 
        return _id;
    }  
    set 
    { 
        _id = value;
    } 
}
public int ParentID 
{  
    get 
    { 
        return _parentId;
    } 
    set 
    { 
        _parentId = value;
    } 
}
public SiteDataItem(int id, int parentId, string text, string url)
{  
    _id = id;
    _parentId = parentId;
    _text = text;
    _url = url;
}

public static List<SiteDataItem> GetSiteData() 
{  
    List<SiteDataItem> siteData = new List<SiteDataItem>();
    siteData.Add(new SiteDataItem(1, 0, "All Sites", ""));  
    siteData.Add(new SiteDataItem(2, 1, "Search Engines", ""));
    siteData.Add(new SiteDataItem(3, 1, "News Sites", ""));
    siteData.Add(new SiteDataItem(4, 2, "Yahoo", "http://www.yahoo.com"));
    siteData.Add(new SiteDataItem(5, 2, "MSN", "http://www.msn.com"));  
    siteData.Add(new SiteDataItem(6, 2, "Google", "http://www.google.com"));  
    siteData.Add(new SiteDataItem(7, 3, "CNN", "http://www.cnn.com"));  
    siteData.Add(new SiteDataItem(8, 3, "BBC", "http://www.bbc.co.uk"));  
    siteData.Add(new SiteDataItem(9, 3, "FOX", "http://www.foxnews.com"));
    return siteData; 
}
}

更多细节,你可以阅读教程dapfor。 COM