views:

64

answers:

3

I was wondering why this doesn't work:

Is it possible to declaratively bind to an Object's property.

<asp:DropDownList id="ddl" runat="server" 
        DataValueField="Key" 
        DataTextField="Value.DisplayName" />

Code Behind

var d = new Dictionary<int, MailAddress>();
d.Add(0,new MailAddress("[email protected]", "Mr. Foo");
d.Add(1,new MailAddress("[email protected]", "Mr. Bar");

ddl.DataSource = d;
ddl.DataBind(); // Error. It doesn't like "DisplayName"
+3  A: 

Check out this post:

http://blogs.msdn.com/b/piyush/archive/2006/10/17/how-to-bind-generic-dictionary-with-dropdown-list.aspx

Change it to:

ddl.DataSource = d.Values; 

and:

DataTextField="DisplayName"

And it should do what you are expecting.

kewlniss
But wouldn't I lose Binding DataValueField to Key then?
Atømix
Confirmed. I'd lose the ability to bind the Key.
Atømix
Is the key not an attribute of the value?
Murph
Nope, The example Binds to the Key of the Dictionary. `System.Net.MailAddress` doesn't have a Key property. The link is useful, however.
Atømix
+1  A: 

I think that it just uses reflection to get the property from the object you set as the data source. You could use linq to wrap your stuff in KetValuePair objects

ddl.DataSource = d.Select(r => new KeyValuePair<string, string>(r.Key, r.Value)).ToList();
Jonathan S.
Ermmm, no......
leppie
That will actually work... with one small change. Obviously changing the DropDownList DataTextField to `Value` and your code to: `...Select(r => new KeyValuePair<string, string>(r.Key.ToString(), r.Value.DisplayName));` You also don't need the `ToList();`
Atømix
your right... i did the example real quick using a Dictionary<string,string> forgot to make the necessary modifications.@leppie thank you for your wonderful and constructive comment. Would you like to elaborate more?
Jonathan S.
@Jonathan S.: It wont compile :)
leppie
A: 

If you are using the .NET MailAddress class, you can create your own class by inheriting from MailAddress, recreating the constructors you will need and overriding the ToString() method to return DisplayName instead of displayName . The just using DataTextField="Value" should work. Like this:

public class MyMailAddress : MailAddress
{

    public MyMailAddress(string emailAddress, string displayName) : base(emailAddress, displayName)
    {

    }
    public override string ToString()
    {
        return base.DisplayName;
    }
}

If you control the code to the class MailAddress, you can override the default ToString() implementation in the class and have it return the DisplayName property, the you can simply set DisplayTextField="Value" like so:

public class MailAddress
{
    public MailAddress(string emailAddress, string displayName)
    {
        _DisplayName = displayName;
        _EmailAddress = emailAddress;
    }
    public MailAddress()
    {
        _DisplayName = "";
        _EmailAddress = "";
    }

    private string _DisplayName;
    public string DisplayName
    {
        get { return _DisplayName; }
        set { _DisplayName = value; }
    }

    private string _EmailAddress;
    public string EmailAddress
    {
        get { return _EmailAddress; }
        set { _EmailAddress = value; }
    }

    public override string ToString()
    {
        return DisplayName;
    }
}
ben f.
I was thinking about this... but I'm using the `System.Net.MailAddress` Class. I don't believe I can override it.
Atømix