views:

418

answers:

1

For example: I have an Contact object on the form (see below). Can i set the datasource propery of the BindingSource to be the property Contact.Addresses.

The class AddressCollection implements BindingList so there is no issue binding this when not encapsulated by the Contact class.

public class Contact : IComparable<Contact>, IComponent
{
    #region Properties
    private AddressCollection addresses = new AddressCollection();
    private ContactNumberCollection contactNumbers = new ContactNumberCollection();

    public int ContactId { get; set; }
    public string Title { get; set; }
    public string Forename { get; set; }
    public string MiddleName { get; set; }
    public string Surname { get; set; }
    public string JobTitle { get; set; }
    public DateTime DateAdded { get; set; }
    public DateTime LastUpdate { get; set; }

    public AddressCollection Addresses
    {
        get { return addresses; }
        set { addresses = value; }
    }
    public ContactNumberCollection ContactNumbers
    {
        get { return contactNumbers; }
        set { contactNumbers = value; }
    }
    #endregion

    #region Constructors
    public Contact()
    {
        DateAdded = DateTime.Now;
        LastUpdate = DateTime.Now;
    }

    #endregion

    public int CompareTo(Contact other)
    {
        return FullName.CompareTo(other.FullName);
    }

    #region IComponent Objects
    private ISite mSite;

    public event EventHandler Disposed;

    public virtual void Dispose()
    {
        if ((mSite != null) && (mSite.Container != null))
        {
            mSite.Container.Remove(this);
        }

        Disposed(this, System.EventArgs.Empty);
    }

    public ISite Site
    {
        get
        {
            return mSite;
        }
        set
        {
            mSite = value;
        }
    }
    #endregion
}

Thanks Anthony

A: 

In short, yes you can. However, if you need to change the contact you may want to set the DataSource to the contact (or the list of contacts) and use the DataMember to "Addresses".

Here's a simplified example showing such binding. If I have missed your point, please clarify:

using System;
using System.ComponentModel;
using System.Windows.Forms;
class AddressCollection : BindingList<Address>
{
    public void Add(string line1, string zip)
    { // just for convenience
        Add(new Address { Line1 = line1, Zip = zip});
    }
}

class Address
{
    public string Line1 { get; set; }
    public string Zip { get; set; }

    public override string ToString()
    {
        return Line1;
    }
}
class Contact
{
    public string Name { get; set; }
    private readonly AddressCollection addresses = new AddressCollection();
    public AddressCollection Addresses { get { return addresses; } }
    public override string ToString()
    {
        return Name;
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        BindingList<Contact> contacts = new BindingList<Contact>
        {
            new Contact { Name = "Fred", Addresses = { {"123 Some road", "AB1"}}},
            new Contact { Name = "Barney", Addresses = { {"456 A Street", "CD2"}, {"789 The Lane", "EF3"}}}                
        };
        BindingSource bs = new BindingSource(contacts, "");

        Form form = new Form { 
            Controls = {
                                new DataGridView { Dock = DockStyle.Fill, DataSource = bs, DataMember = "Addresses" },
                new ComboBox { Dock = DockStyle.Top, DataSource = bs, DisplayMember = "Name" },
                new TextBox { Dock = DockStyle.Bottom, DataBindings = { {"Text", bs, "Addresses.Zip"}}}
            }
        };
        Application.Run(form);

    }
}
Marc Gravell
This is what I had in mind and you're example was helpful. The only issue is on the form, the contact is defined: BusinessObjects.Contact currentCustomer; instead of having a collection of customers.I could simply have a collection with one item in it however this just seems untidy?
Anthony