asp.net 向绑定到DropDownList的SqlDataSource添加空白的第一行

3zwtqj6y  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(122)

因此,我有一个ASP.NET页面的材料订购,在那里用户可以订购组件的生产一个给定的产品。它的结构方式:

  • 第一个DropDownList使用SqlDataSource列出所有活动的生产线
  • 用户选择生产线
  • 第二个DropDownList使用SqlDataSource列出了该生产线上生产的所有产品,该SqlDataSource的ControlParameter设置为使用第一个DropDownList中的生产线
  • 用户选择产品
  • 第三个DropDownList列出了该产品所需的所有组件,使用SqlDataSource和ControlParameter,该ControlParameter设置为使用第二个DropDownList中的产品

下面你可以看到它的样子:

<div class="input-group mb-3">
  <asp:DropDownList ID="ProductionLine" runat="server" CssClass="form-control" AutoPostBack="true" OnSelectedIndexChanged="ProductionLine_SelectedIndexChanged">
    <asp:ListItem Text="Choose a production line..." Value="" Hidden="true" />
    <asp:ListItem Text="Band 45" Value="Band 45" />
    <asp:ListItem Text="Band 46" Value="Band 46" />
    <asp:ListItem Text="Band 47" Value="Band 47" />
    <asp:ListItem Text="Band 48" Value="Band 48" />
  </asp:DropDownList>
  <asp:DropDownList ID="Product" runat="server" CssClass="form-control" Enabled="false" AutoPostBack="true" OnSelectedIndexChanged="Product_SelectedIndexChanged" DataSourceID="Products" DataTextField="Material" DataValueField="Material" AppendDataBoundItems="true">
    <asp:ListItem Text="Choose a product..." Value="" Hidden="true" />
  </asp:DropDownList>
  <asp:DropDownList ID="Component" runat="server" CssClass="form-control" Enabled="false" AutoPostBack="true" OnSelectedIndexChanged="Component_SelectedIndexChanged" DataSourceID="Components" DataTextField="Component" DataValueField="Component" AppendDataBoundItems="true">
    <asp:ListItem Text="Choose a component..." Value="" Hidden="true" />
  </asp:DropDownList>
</div>
<asp:SqlDataSource ID="Products" runat="server" ConnectionString='<%$ ConnectionStrings:conn %>' SelectCommand="SELECT DISTINCT SUBSTRING([Material],1, 4) + '.' + SUBSTRING([Material], 5, 3) + '.' + SUBSTRING([Material], 8, 3) AS 'Material' FROM [RBBE_sl_scan_log] WHERE [ProdLine] = @ProdLine">
  <SelectParameters>
    <asp:ControlParameter Name="ProdLine" ControlID="ProductionLine" PropertyName="SelectedValue" />
  </SelectParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="Components" runat="server" ConnectionString='<%$ ConnectionStrings:conn %>' SelectCommand="SELECT DISTINCT [Component] FROM [RBBE_sl_BOM] WHERE [Material] = @Material">
  <SelectParameters>
    <asp:ControlParameter Name="Material" ControlID="Product" PropertyName="SelectedValue" />
  </SelectParameters>
</asp:SqlDataSource>

字符串
到目前为止,这一切都很好,但我想在每个DropDownList的开头添加一个空行,形式为“选择生产线...”,“选择产品...”和“选择组件...”。正如您所看到的,我手动添加了这些空白值,然后在DropDownLists上使用 AppendDataBoundItems=“true”,因此一旦SqlDataSource填充了这些值,就不会删除这一空白行。
问题是,这样一来,每次DropDownList的选定索引更改时,SqlDataSource中的行都会再次追加,这意味着DropDownList最终将拥有越来越多的选项,而不是旧选项消失,新选项出现。当然,解决方案是从DropDownLists中删除 AppendDataBoundItems=“true” 设置,但手动添加的空白行也会被删除。
在这种情况下,什么是最好/最干净的方法来保留第一个空白行,同时也使DropDownLists正确地重新绑定新值?我知道我可以在数据绑定后从后面的代码中添加空白行,但我希望有一个更干净的解决方案。在SQL查询中使用UNION添加空白行也不是一种选择,因为我想用不同的语言本地化页面。

wj8zmpe1

wj8zmpe11#

好吧,“最好的”代码是相当主观的。
我建议构建一个项目中所有此类代码都可以使用的简单例程。
在这个例子中,我们有一个由2个组合框组成的“公共”级联。
我们选择一个城市,然后将第二个组合与该城市的酒店级联(过滤)。
所以,这个标记:

<div style="float:left">
            <h3>Select City</h3>
            <asp:DropDownList ID="cboCity" runat="server" Width="200px"
                AutoPostBack="true"
                OnSelectedIndexChanged="cboCity_SelectedIndexChanged" >
            </asp:DropDownList>
        </div>

        <div style="float:left;margin-left:25px">
            <h3>Select Hotel</h3>
            <asp:DropDownList ID="cboHotels" runat="server" Width="200px" >
            </asp:DropDownList>
        </div>

字符串
网页上的代码是这样的:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadCityCbo();
    }

    void LoadCityCbo()
    {
        SqlCommand cmd = 
            new SqlCommand("Select City FROM City ORDER BY City");
        General.Cbo(cboCity, cmd, "", "City", "Select City");
    }

    protected void cboCity_SelectedIndexChanged(object sender, EventArgs e)
    {
        // cascade
        SqlCommand cmd =
            new SqlCommand(@"SELECT ID, HotelName
                           FROM tblhotelsA WHERE City = @City
                           ORDER BY HotelName");

        cmd.Parameters.Add("@City", SqlDbType.NVarChar).Value = cboCity.SelectedItem.Text;
        General.Cbo(cboHotels, cmd, "ID", "HotelName", "Select Hotel");
    }


因此,上述方法允许设置组合框的数据源、“值”和“文本”字段设置以及额外的提示行。
在我们的“通用”catch all类(所有网页和代码都使用)中,我们有以下2个例程。

public static void Cbo(DropDownList ddl,
                    SqlCommand cmd,
                    string sValue, string sText,
                    string sPrompt)
{
    ddl.DataValueField = sValue;
    ddl.DataTextField = sText;
    ddl.DataSource = General.MyRstP(cmd);
    ddl.DataBind();
    ddl.Items.Insert(0, sPrompt);
}

public static DataTable MyRstP(SqlCommand cmdSQL)
{
    using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
    {
        using (cmdSQL)
        {
            cmdSQL.Connection = conn;
            conn.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
    }
    return rstData;
}

相关问题