2

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

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

我已经尝试了一系列想法,但似乎找不到任何关于这是否可以完成的信息。

4

3 回答 3

5

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

尝试这样的事情:

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

ddl.DataSource = users.ConvertAll(u => 
    new { Value = u.Name, Telephone = u.ContactDetails.Telephone });
ddl.DataTextField = "Telephone";
于 2009-02-12T13:40:46.930 回答
2

编辑: 我得到了足够多的关于这个话题的反馈,我觉得它值得写一篇博文

在将域对象绑定到 ddl 控件时,我采用的一种方法是从在 constr 中具有重载的基类继承,以允许文本/值仅是原始的“子集”。下面的代码用于模型视图演示器或模型视图 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 的定义

 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)

这是特定于 Web 的 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 您的视图的只读属性看起来像,这里是 WPF 特定 ddl 的实现- Return New 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; }
     }
 }

你一次只需要其中一个,但我认为展示这两个将有助于清楚我们正在抽象的内容

因为这是一个巨大的答案,如果需要,我可以发布一个示例项目以供下载,以显示此操作 - 让我知道

于 2009-02-12T13:42:53.370 回答
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();
于 2009-02-12T14:24:32.940 回答