Allen
Allen

Reputation: 203

Data Binding to an object in C#

Objective-c/cocoa offers a form of binding where a control's properties (ie text in a textbox) can be bound to the property of an object. I am trying to duplicate this functionality in C# w/ .Net 3.5.

I have created the following very simple class in the file MyClass.cs:

class MyClass
{
    private string myName;

    public string MyName
    {
        get
        {
            return myName;
        }

        set
        {
            myName = value;
        }
    }

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

I also created a simple form with 1 textbox and 1 button. I init'd one instance of Myclass inside the form code and built the project. Using the DataSource Wizard in Vs2008, I selected to create a data source based on object, and selected the MyClass assembly. This created a datasource entity. I changed the databinding of the textbox to this datasource; however, the expected result (that the textbox's contents would be "allen") was not achieved. Further, putting text into the textbox is not updating the name property of the object.

I know i'm missing something fundamental here. At some point i should have to tie my instance of the MyClass class that i initialized inside the form code to the textbox, but that hasn't occurred. Everything i've looked at online seems to gloss over using DataBinding with an object (or i'm missing the mark entirely), so any help is great appreciated.

Edit:

Utilizing what I learned by the answers, I looked at the code generated by Visual Studio, it had the following:

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

if I comment that out and substitute:

this.myClassBindingSource.DataSource = new MyClass();

I get the expected behavior. Why is the default code generated by VS like it is? Assuming this is more correct than the method that works, how should I modify my code to work within the bounds of what VS generated?

Upvotes: 19

Views: 53938

Answers (6)

Ron Maman
Ron Maman

Reputation: 51

I get an error message in the DataBinding.Add("TEXT", myObject, myObjectProperty) method

This is probably because you're missing the explicit {get;set;} on the property declaration!

BAD:

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

GOOD:

public string FirstName { get; set; }

Upvotes: 5

Alastairgraeme
Alastairgraeme

Reputation: 9

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

More detail you can read tutorial dapfor. com

Upvotes: 0

Jason Coyne
Jason Coyne

Reputation: 6636

You must assign the textbox's data source to be your new datasource. But additionally, you must assign the datasource's datasource to be an instance of your class.

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

That should work for your first pass. As others have mentioned, you may need to implement additional interfaces on your class (INotifyPropertyChanged etc), if you are going to be modifying the class properties via any background processes.

If you are only updating the properties via the form, then you do not need this step.

Upvotes: 14

Don Kirkby
Don Kirkby

Reputation: 56230

I don't have any code in front of me, but I think the data source is kind of like a collection. You have to add an instance of MyClass to the data source, and that's what the form fields will bind to. There's also methods for navigating through the data source to multiple instances of MyClass, but it doesn't sound like you need that. Check the docs for DataSource.

I don't think you need to implement any fancy interfaces. I seem to remember there's a method on the data source that lets you refresh or rebind the current item after you change some values.

Upvotes: 0

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107606

Looks like you probably need a Bindable attribute on your MyName property (and follow Frederik's suggestion as well):

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

Via: http://support.microsoft.com/kb/327413

Upvotes: 0

Frederik Gheysels
Frederik Gheysels

Reputation: 56974

You should implement the INotifyPropertyChanged interface to your MyClass type:

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

This interface is required for the DataBinding infrastructure if you want to support simple databinding. The INotifyPropertyChanged interface is used to notify a 'binding' that a property has changed, so the DataBinding infrastructure can act accordingly to it.

Then, you can databind the MyName property to the Text Property of the textbox.

Upvotes: 12

Related Questions