如何绑定对象中的 DropDownlist DataText 或 DataValue 字段。当有问题的对象处于第二级时,例如要绑定的对象不在返回对象 Users.ContactDetails.Telephone 的第一级,因为下面的代码不起作用:
ddl.DataSource = dal.dal_Users.GetAllUsers();
ddl.DataTextField = "Telephone";
我已经尝试了一系列想法,但似乎找不到任何关于这是否可以完成的信息。
如何绑定对象中的 DropDownlist DataText 或 DataValue 字段。当有问题的对象处于第二级时,例如要绑定的对象不在返回对象 Users.ContactDetails.Telephone 的第一级,因为下面的代码不起作用:
ddl.DataSource = dal.dal_Users.GetAllUsers();
ddl.DataTextField = "Telephone";
我已经尝试了一系列想法,但似乎找不到任何关于这是否可以完成的信息。
如果您使用的是 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";
编辑: 我得到了足够多的关于这个话题的反馈,我觉得它值得写一篇博文
在将域对象绑定到 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; }
}
}
你一次只需要其中一个,但我认为展示这两个将有助于清楚我们正在抽象的内容
因为这是一个巨大的答案,如果需要,我可以发布一个示例项目以供下载,以显示此操作 - 让我知道
我能看到这可以在.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();