来自对象的DropDownList

时间:2009-02-12 13:00:40

标签: c# .net drop-down-menu

如何从对象绑定DropDownlist DataText或DataValue字段。 当所讨论的对象处于第二级时,例如要绑定的对象不在返回的对象Users.ContactDetails.Telephone的第一级,因为下面的代码不起作用:

ddl.DataSource = dal.dal_Users.GetAllUsers();
ddl.DataTextField = "Telephone";

我尝试了一系列想法,但似乎无法找到有关是否可以这样做的任何信息。

3 个答案:

答案 0 :(得分:5)

如果您使用的是C#3,那么您可以使用ConvertAll<>扩展方法创建一个新的匿名类型,将内部属性移动到顶层。

尝试这样的事情:

IEnumerable<User> users = dal.dal_Users.GetAllUsers();

ddl.DataSource = users.ConvertAll(u => 
    new { Value = u.Name, Telephone = u.ContactDetails.Telephone });
ddl.DataTextField = "Telephone";

答案 1 :(得分:2)

编辑:我对此主题有足够的反馈,我觉得它值得blog post

我将域对象绑定到ddl控件时采用的一种方法是从构造中具有重载的基类继承,以允许仅原始文本/值的“子集”。下面的代码用于模型视图展示器或模型视图ViewModel实现,该实现抽象出ddl控件,因此您可以在此业务代码的顶部推送任何UI。

下面是我如何将ddl与用户对象集合绑定的示例,并根据相关对象(工作单元)设置所选对象

 public void PopulateUserDDL(UnitOfWork UnitOfWorkObject)
 {
     List<User> UserCollection = mUserService.GetUserCollection();  //get a collection of objects to bind this ddl

     List<ILookupDTO> UserLookupDTO = new List<ILookupDTO>();

     UserLookupDTO.Add(new User(" ", "0"));
     //insert a blank row ... if you are into that type of thing

     foreach (var User in UserCollection) {
         UserLookupDTO.Add(new User(User.FullName, User.ID.ToString()));
     }

     LookupCollection LookupCollectionObject = new LookupCollection(UserLookupDTO);
     LookupCollectionObject.BindTo(mView.UserList);

     if (UnitOfWorkObject == null) {
         return;
     }

     if (UserCollection == null) {
         return;
     }

     for (i = 0; i <= UserCollection.Count - 1; i++) {
         if (UserCollection(i).ID == UnitOfWorkObject.User.ID) {
             LookupCollectionObject.SelectedIndex = (i + 1);
             //because we start at 0 instead of 1 (we inserted the blank row above)
             break;
         }
     }
 }

下面是用户对象中的重载

/// <summary>
/// This constr is used when you want to create a new Lookup Collection of ILookupDTO
/// </summary>
/// <param name="txt">The text that will show up for the user in the lookup collection</param>
/// <param name="val">The value that will be attached to the item in the lookup collection</param>
/// <remarks></remarks>
public New(string txt, string val) : base(txt, val)
{
}
任何实体/域对象/ DTO /等的基类都需要

 public New(string txt, string val)
 {
     mText = txt;
     mValue = val;
 }

此基类还应实现ILookupDTO - 因为这会强制您公开本示例中用户对象使用的Text和Value属性

 public interface ILookupDTO
 {
     string Text {
         get;
         set;
     }
     string Value {
         get;
         set;
     }
 }

以下是此答案顶部的bind方法中使用的LookupCollection的def

 public class LookupCollection
 {
     private readonly IEnumerable<ILookupDTO> dtos;
     private ILookupList mList;

     public LookupCollection(IEnumerable<ILookupDTO> dtos)
     {
         this.dtos = dtos;
     }

     public void BindTo(ILookupList list)
     {
         mList = list;

         mList.Clear();

         foreach (ILookupDTO dto in dtos) {
             mList.Add(dto);
         }
     }

     public int SelectedIndex {
         get { return mList.SelectedIndex; }
         set { mList.SelectedIndex = value; }
     }

     public string SelectedValue {
         get { return mList.SelectedValue; }
         set { mList.SelectedValue = value; }
     }
 }

下面是ILookupList的接口 - 用于实现每个UI特定控件(参见下面的web和wpf示例)

 public interface ILookupList
 {
     void Add(ILookupDTO dto);
     void Clear();
     int Count();
     int SelectedIndex {
         get;
         set;
     }
     string SelectedValue {
         get;
         set;
     }
 }

现在在您的代码隐藏中,您需要在视图的只读属性中执行类似的操作

返回新的WebLookupList(ddlUsers)

此处是特定于网络的ddl

的实施方案
 public class WebLookupList : ILookupList
 {

     private readonly ListControl listControl;

     public WebLookupList(ListControl listControl)
     {
         this.listControl = listControl;
     }

     public void Clear()
     {
         listControl.Items.Clear();
     }

     public void Add(Interfaces.ILookupDTO dto)
     {
         listControl.Items.Add(new ListItem(dto.Text, dto.Value));
     }

     public int Count()
     {
         return listControl.Items.Count;
     }

     public int SelectedIndex {
         get { return listControl.SelectedIndex; }
         set { listControl.SelectedIndex = value; }
     }

     public string SelectedValue {
         get { return listControl.SelectedValue; }
         set { listControl.SelectedValue = value; }
     }
 }

这是WPF特定ddl 的实现 如果使用wpf,则视图的只读属性将如下所示 - 返回新的WPFLookupList(ddlUsers)

 public class WPFLookupList : ILookupList
 {

     private readonly ComboBox combobox;

     public WPFLookupList(ComboBox combobox)
     {
         this.combobox = combobox;
     }

     public void Add(Interfaces.ILookupDTO dto)
     {
         ComboBoxItem item = new ComboBoxItem();
         item.Content = dto.Text;
         item.Tag = dto.Value;

         combobox.Items.Add(item);
     }

     public void Clear()
     {
         combobox.Items.Clear();
     }

     public int Count()
     {
         return combobox.Items.Count;
     }

     public int SelectedIndex {
         get { return combobox.SelectedIndex; }
         set { combobox.SelectedIndex = value; }
     }

     public string SelectedValue {
         get { return combobox.SelectedValue.Tag; }
         set { combobox.SelectedValue.Tag = value; }
     }
 }

你一次只需要其中的一个,但我认为两者都有助于明确我们的摘要

因为这是一个如此巨大的答案,我可以发布一个示例项目供下载,如果需要可以显示这个 - 请告诉我

答案 2 :(得分:1)

我能看到这可以在.Net 2.0中完成的唯一方法就是这样

  List<Users> userList = dal_Users.GetAllUsers();

  foreach (Users u in userList )
  {
     ListItem li = new ListItem();
     li.Text = u.ContactDetails.Telephone;
     li.Value = u.userID.ToString();
     ddl.Items.Add(li);
  }

  ddl.DataBind();