DataBindings

  • Thread starter Thread starter Trecius
  • Start date Start date
T

Trecius

Hello, Newsgroupians:

Is it possible to data bind on a property of a property?

For example, I have a class Person. It has a person's name, age, and a
ADDRESS. Address is another class that just contains 2 properties: Number
and Street.

I want the text box to bind to a person, but also display the person's
street name.

I'd like to type the following...

TextBoxFirstChild.DataBindings.Add("Text", PersonOfInterest,
"Address.Street") but that doesn't work.

Is it possible to do what I'm asking? I could probably write a Property
into the Person, called StreetAddressName, but I'd like not to do this if
possible.

Thank you.


Trecius
 
TextBoxFirstChild.DataBindings.Add("Text", PersonOfInterest.Address,
"Street") should be what you are looking for? Mind, PersonOfInterest must represent an instance of the Person class.

André
 
Ack, I my mistake. Here's what I have...

List<Person> lstPersons = GetPersons();
TextBoxFirstChild.DataBindings.Add("Text", lstPersons, "Address.Street");

Sorry for the misunderstanding.


Trecius
 
It will work like this:
TextBoxFirstChild.DataBindings.Add("Text", lstPersons[1].Address, "Street");

This is probably not what you want, I guess you want the Streetname to
change when another person is selected. A simple solution to this is to
abandon the databinding altogether and simply write a method that assigns the
street property to the Text property of the textbox whenever another Person
is under scrutiny.

public void OnNewPersonOfInterest(int index)
{
textBox1.Text=lstPersons[index].Address.Street;
}
 
Hi Trecious,

You sure can and the code below demonstrates a simple examle on how this is
done. Note however that databinding can break if you bind on properties that
may be null. If you wrap your datasource in a BindingSource you will be able
to do even more complex databinding. A BindingList<T> is a List<T> that will
notify when you add or remove items from the list. If you make changes to
Person in code you will need to implement INotifyPropertyChanged and raise a
PropertyChanged event for the properties you change. If you want the
underlying datasource to be updated as you type on screen, change the
DataBinding type to OnPropertyChanged. Try clicking the button with and
without using a BindingSource. You will update the Age in both cases, but
unless you use a BindingSource you will have to reselect the Person in the
list to see the change.

--
Happy Coding!
Morten Wennevik [C# MVP]

public partial class Form1 : Form
{
BindingSource bs = new BindingSource();
ComboBox comboPerson = new ComboBox();
TextBox textBoxAge = new TextBox();
TextBox textBoxStreet = new TextBox();
Button b = new Button { Text = "Add year" };

public Form1()
{
Controls.Add(comboPerson);
textBoxAge.Top = comboPerson.Bottom + 5;
Controls.Add(textBoxAge);
textBoxStreet.Top = textBoxAge.Bottom + 5;
Controls.Add(textBoxStreet);
b.Top = textBoxStreet.Bottom + 5;
b.Click += Button_Click;
Controls.Add(b);
}

protected override void OnLoad(EventArgs e)
{
List<Person> people = new List<Person>();
people.Add(new Person
{
Name = "Bonnie Baxter",
Age = 25,
Address = new Address { Street = "Baxterville 25" }
});
people.Add(new Person
{
Name = "Clyde Stirrup",
Age = 64,
Address = new Address { Street = "Clystir road 52" }
});
people.Add(new Person
{
Name = "Baker Field",
Age = 37,
Address = new Address { Street = "234 North Hollywood" }
});

// Without BindingSource
comboPerson.DataSource = people;
comboPerson.DisplayMember = "Name";
textBoxAge.DataBindings.Add("Text", people, "Age");
textBoxStreet.DataBindings.Add("Text", people, "Address.Street");

// With BindingSource
//bs.DataSource = people;
//comboPerson.DataSource = bs;
//comboPerson.DisplayMember = "Name";
//textBoxAge.DataBindings.Add("Text", bs, "Age");
//textBoxStreet.DataBindings.Add("Text", bs, "Address.Street");
}

void Button_Click(object sender, EventArgs e)
{
Person p = comboPerson.SelectedItem as Person;
p.Age++;
}

class Person : INotifyPropertyChanged
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set { _age = value; NotifyChanged("Age"); }

}
public Address Address { get; set; }

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

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

class Address
{
public string Street { get; set; }
}
}
 
Hi Trecious,

You sure can and the code below demonstrates a simple examle on how this is
done. Note however that databinding can break if you bind on properties that
may be null. If you wrap your datasource in a BindingSource you will be able
to do even more complex databinding. A BindingList<T> is a List<T> that will
notify when you add or remove items from the list. If you make changes to
Person in code you will need to implement INotifyPropertyChanged and raise a
PropertyChanged event for the properties you change. If you want the
underlying datasource to be updated as you type on screen, change the
DataBinding type to OnPropertyChanged. Try clicking the button with and
without using a BindingSource. You will update the Age in both cases, but
unless you use a BindingSource you will have to reselect the Person in the
list to see the change.

--
Happy Coding!
Morten Wennevik [C# MVP]

public partial class Form1 : Form
{
BindingSource bs = new BindingSource();
ComboBox comboPerson = new ComboBox();
TextBox textBoxAge = new TextBox();
TextBox textBoxStreet = new TextBox();
Button b = new Button { Text = "Add year" };

public Form1()
{
Controls.Add(comboPerson);
textBoxAge.Top = comboPerson.Bottom + 5;
Controls.Add(textBoxAge);
textBoxStreet.Top = textBoxAge.Bottom + 5;
Controls.Add(textBoxStreet);
b.Top = textBoxStreet.Bottom + 5;
b.Click += Button_Click;
Controls.Add(b);
}

protected override void OnLoad(EventArgs e)
{
List<Person> people = new List<Person>();
people.Add(new Person
{
Name = "Bonnie Baxter",
Age = 25,
Address = new Address { Street = "Baxterville 25" }
});
people.Add(new Person
{
Name = "Clyde Stirrup",
Age = 64,
Address = new Address { Street = "Clystir road 52" }
});
people.Add(new Person
{
Name = "Baker Field",
Age = 37,
Address = new Address { Street = "234 North Hollywood" }
});

// Without BindingSource
comboPerson.DataSource = people;
comboPerson.DisplayMember = "Name";
textBoxAge.DataBindings.Add("Text", people, "Age");
textBoxStreet.DataBindings.Add("Text", people, "Address.Street");

// With BindingSource
//bs.DataSource = people;
//comboPerson.DataSource = bs;
//comboPerson.DisplayMember = "Name";
//textBoxAge.DataBindings.Add("Text", bs, "Age");
//textBoxStreet.DataBindings.Add("Text", bs, "Address.Street");
}

void Button_Click(object sender, EventArgs e)
{
Person p = comboPerson.SelectedItem as Person;
p.Age++;
}

class Person : INotifyPropertyChanged
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set { _age = value; NotifyChanged("Age"); }

}
public Address Address { get; set; }

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

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

class Address
{
public string Street { get; set; }
}
}
 
Thank you, Mr. Wennevik.

Morten Wennevik said:
Hi Trecious,

You sure can and the code below demonstrates a simple examle on how this is
done. Note however that databinding can break if you bind on properties that
may be null. If you wrap your datasource in a BindingSource you will be able
to do even more complex databinding. A BindingList<T> is a List<T> that will
notify when you add or remove items from the list. If you make changes to
Person in code you will need to implement INotifyPropertyChanged and raise a
PropertyChanged event for the properties you change. If you want the
underlying datasource to be updated as you type on screen, change the
DataBinding type to OnPropertyChanged. Try clicking the button with and
without using a BindingSource. You will update the Age in both cases, but
unless you use a BindingSource you will have to reselect the Person in the
list to see the change.

--
Happy Coding!
Morten Wennevik [C# MVP]

public partial class Form1 : Form
{
BindingSource bs = new BindingSource();
ComboBox comboPerson = new ComboBox();
TextBox textBoxAge = new TextBox();
TextBox textBoxStreet = new TextBox();
Button b = new Button { Text = "Add year" };

public Form1()
{
Controls.Add(comboPerson);
textBoxAge.Top = comboPerson.Bottom + 5;
Controls.Add(textBoxAge);
textBoxStreet.Top = textBoxAge.Bottom + 5;
Controls.Add(textBoxStreet);
b.Top = textBoxStreet.Bottom + 5;
b.Click += Button_Click;
Controls.Add(b);
}

protected override void OnLoad(EventArgs e)
{
List<Person> people = new List<Person>();
people.Add(new Person
{
Name = "Bonnie Baxter",
Age = 25,
Address = new Address { Street = "Baxterville 25" }
});
people.Add(new Person
{
Name = "Clyde Stirrup",
Age = 64,
Address = new Address { Street = "Clystir road 52" }
});
people.Add(new Person
{
Name = "Baker Field",
Age = 37,
Address = new Address { Street = "234 North Hollywood" }
});

// Without BindingSource
comboPerson.DataSource = people;
comboPerson.DisplayMember = "Name";
textBoxAge.DataBindings.Add("Text", people, "Age");
textBoxStreet.DataBindings.Add("Text", people, "Address.Street");

// With BindingSource
//bs.DataSource = people;
//comboPerson.DataSource = bs;
//comboPerson.DisplayMember = "Name";
//textBoxAge.DataBindings.Add("Text", bs, "Age");
//textBoxStreet.DataBindings.Add("Text", bs, "Address.Street");
}

void Button_Click(object sender, EventArgs e)
{
Person p = comboPerson.SelectedItem as Person;
p.Age++;
}

class Person : INotifyPropertyChanged
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set { _age = value; NotifyChanged("Age"); }

}
public Address Address { get; set; }

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

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

class Address
{
public string Street { get; set; }
}
}


Trecius said:
Hello, Newsgroupians:

Is it possible to data bind on a property of a property?

For example, I have a class Person. It has a person's name, age, and a
ADDRESS. Address is another class that just contains 2 properties: Number
and Street.

I want the text box to bind to a person, but also display the person's
street name.

I'd like to type the following...

TextBoxFirstChild.DataBindings.Add("Text", PersonOfInterest,
"Address.Street") but that doesn't work.

Is it possible to do what I'm asking? I could probably write a Property
into the Person, called StreetAddressName, but I'd like not to do this if
possible.

Thank you.


Trecius
 
Thank you, Mr. Wennevik.

Morten Wennevik said:
Hi Trecious,

You sure can and the code below demonstrates a simple examle on how this is
done. Note however that databinding can break if you bind on properties that
may be null. If you wrap your datasource in a BindingSource you will be able
to do even more complex databinding. A BindingList<T> is a List<T> that will
notify when you add or remove items from the list. If you make changes to
Person in code you will need to implement INotifyPropertyChanged and raise a
PropertyChanged event for the properties you change. If you want the
underlying datasource to be updated as you type on screen, change the
DataBinding type to OnPropertyChanged. Try clicking the button with and
without using a BindingSource. You will update the Age in both cases, but
unless you use a BindingSource you will have to reselect the Person in the
list to see the change.

--
Happy Coding!
Morten Wennevik [C# MVP]

public partial class Form1 : Form
{
BindingSource bs = new BindingSource();
ComboBox comboPerson = new ComboBox();
TextBox textBoxAge = new TextBox();
TextBox textBoxStreet = new TextBox();
Button b = new Button { Text = "Add year" };

public Form1()
{
Controls.Add(comboPerson);
textBoxAge.Top = comboPerson.Bottom + 5;
Controls.Add(textBoxAge);
textBoxStreet.Top = textBoxAge.Bottom + 5;
Controls.Add(textBoxStreet);
b.Top = textBoxStreet.Bottom + 5;
b.Click += Button_Click;
Controls.Add(b);
}

protected override void OnLoad(EventArgs e)
{
List<Person> people = new List<Person>();
people.Add(new Person
{
Name = "Bonnie Baxter",
Age = 25,
Address = new Address { Street = "Baxterville 25" }
});
people.Add(new Person
{
Name = "Clyde Stirrup",
Age = 64,
Address = new Address { Street = "Clystir road 52" }
});
people.Add(new Person
{
Name = "Baker Field",
Age = 37,
Address = new Address { Street = "234 North Hollywood" }
});

// Without BindingSource
comboPerson.DataSource = people;
comboPerson.DisplayMember = "Name";
textBoxAge.DataBindings.Add("Text", people, "Age");
textBoxStreet.DataBindings.Add("Text", people, "Address.Street");

// With BindingSource
//bs.DataSource = people;
//comboPerson.DataSource = bs;
//comboPerson.DisplayMember = "Name";
//textBoxAge.DataBindings.Add("Text", bs, "Age");
//textBoxStreet.DataBindings.Add("Text", bs, "Address.Street");
}

void Button_Click(object sender, EventArgs e)
{
Person p = comboPerson.SelectedItem as Person;
p.Age++;
}

class Person : INotifyPropertyChanged
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set { _age = value; NotifyChanged("Age"); }

}
public Address Address { get; set; }

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

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

class Address
{
public string Street { get; set; }
}
}


Trecius said:
Hello, Newsgroupians:

Is it possible to data bind on a property of a property?

For example, I have a class Person. It has a person's name, age, and a
ADDRESS. Address is another class that just contains 2 properties: Number
and Street.

I want the text box to bind to a person, but also display the person's
street name.

I'd like to type the following...

TextBoxFirstChild.DataBindings.Add("Text", PersonOfInterest,
"Address.Street") but that doesn't work.

Is it possible to do what I'm asking? I could probably write a Property
into the Person, called StreetAddressName, but I'd like not to do this if
possible.

Thank you.


Trecius
 
Back
Top