ASP.NET WebForms DropDownList数据绑定奇怪的行为?

Wil*_*ler 5 asp.net data-binding webforms drop-down-menu

摘要

我将数据上下文中的城市加载到两个不同的列表中,并将它们绑定到各自的DropDownList控件.

虽然两者的代码相同,但只有数据和显然控件的名称不同,数据绑定似乎不适用于其中一个.它不显示城市名称,而是显示其ID,即仅用于第一个选项!

代码隐藏

我们有两个DropDownList控件:

  1. DestinationDropDownList;
  2. OriginDropDownList.

然后,我填充他们.

public partial class MyControl : UserControl {
    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            var instruction = new City() {
                CityId = Guid.Empty,
                CityName = "- Select a city -"
            };

            var destinations = context.Cities.ToList();
            destinations = destinations.OrderBy(c => c.CityName).ToList();
            destinations.Insert(0, instruction);
            DestinationDropDownList.DataSource = destinations;
            DestinationDropDownList.DataTextField = "CityName";
            DestinationDropDownList.DataValueField = "CityId";
            DestinationDropDownList.DataBind();

            var origins = context.Cities.ToList();
            origins = origins.OrderBy(c => c.CityName).ToList();
            origins.Insert(0, instruction);
            OriginDropDownList.DataSource = origins;
            OriginDropDownList.DataTextField = "CityName";
            OriginDropDownList.DataValueField = "CityId";
            OriginDropDownList.DataBind();
        }
    }
    private static readonly MyDataContext context = new MyDataContext();
}
Run Code Online (Sandbox Code Playgroud)

HTML

<asp:DropDownList ID="DestinationDropDownList" runat="server" />
<asp:DropDownList ID="OriginDropDownList" runat="server" />
Run Code Online (Sandbox Code Playgroud)

数据显示

*DestinationDropwDownList*
    - 0000-0000-0000-0000-0000 (empty Guid)
    - CityName 01
    - CityName 02
    - ...

*OriginDropDownList*
    - - Select a city -
    - CityName 01
    - CityName 02
    - ...
Run Code Online (Sandbox Code Playgroud)

正确的显示是由OriginDropDownList控件呈现的显示.为什么DestinationDropDownList不正确显示数据,也就是说,列表中第一个也是唯一的第一个项目!?我根本没有得到它,并且已经花了几个小时试图找到解决方案!=(

  1. 我在插入指令之前尝试删除第一项;
  2. 我试图插入指令两次,然后删除第一个;
  3. 我试着继续使用这个DropDownList.Items.Add(string)方法,这显示的不是第一行,而是空Guid.

问题

  1. 有没有人遇到过DropDownList控件的问题?
  2. 如何纠正这种行为!?

编辑#1

michielvoo的回答帮助我找到了一种新的数据绑定方式.通过他的代码,找到的解决方法是这样的:

<asp:DropDownList ID="DestinationDropDownList" runat="server"
                  AppendDataBoundItems="true"
                  CssClass="required">
    <asp:ListItem Value="- Select a city -" />
</asp:DropDownList>
Run Code Online (Sandbox Code Playgroud)

仅从此DropDownList的代码中删除指令插入.现在它从头开始显示我想要的内容.

我接受了他的答案,因为正是他带领我找到了一个很好的解决方法.我不觉得这是真正的解决方案,但只要结果是他们的,我不介意.除了Guid.Empty验证页面的验证,我将不得不检查我的指令,并在用户没有选择位于另一个索引而不是0的城市时使页面无效,因为我的检查Guid会失败.

编辑#2

使用michielvoo的答案中所述的代码隐藏,它完全解决了我DropDownList显示ListItem.Value属性的问题,而ListITem.Text不仅仅是属性,只有列表中的第一项.我不知道其他方面有什么问题,但是这个方法很棒!

谢谢michielvoo!

谢谢大家的支持!=)

Mic*_*out 7

我之前没有遇到过这个问题,但我会尽力回答你的第二个问题.我认为通过代码添加第一个'教学'项目没什么价值(如果我错了,请纠正我).我宁愿直接添加到加价中:

<asp:DropDownList ID="DestinationDropwDownList" runat="server"
  AppendDataBoundItems="true"
  DataTextField="CityName"
  DataTextField="CityId">
  <asp:ListItem Text="- Select a city -" />
</asp:DropDownList>
Run Code Online (Sandbox Code Playgroud)

由于使用了AppendDataBoundItems属性,第一项将在数据绑定中继续存在.我还添加了DataTextFieldDataValueField属性,您也可以从代码中删除它们.

在数据绑定之前可以做的另一件事是将实体投影到ListItem实例:

DestinationDropDownList.DataSource = 
  from d in destinations
  select new ListItem() {
    Text = d.CityName,
    Value = d.CityId.ToString()
  };
DestinationDropDownList.DataBind();
Run Code Online (Sandbox Code Playgroud)

这样,您就不必在控件上设置DataTextFieldDataValueField属性,因为您已经自己创建了列表的项目.