Combobox在数据库填充时将值加倍

时间:2018-06-11 14:48:00

标签: c# winforms combobox

我使用C#Winforms和SQL Server作为我的数据库。

在我的Combobox_Leave事件中,它会使用前一个

的文本值填充其他Combobox

这是我的Combobox_Leave事件之一,与其他Combobox

类似
private void cmbPItem_Leave(object sender, EventArgs e)
{
    using (SqlConnection conn = new SqlConnection(@"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + ""))
    {
        conn.Open();
        using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT DISTINCT [Brand]
                                                        FROM [dbo].[products] WHERE Item LIKE '" + cmbPItem.Text + "'", conn))
        {
            DataTable dt = new DataTable();
            sda.Fill(dt);
            if (dt.Rows.Count != 0)
            {
                cmbPBrand.Items.Clear();
                for (int b = 0; b < dt.Rows.Count; b++)
                {
                    cmbPBrand.Items.Add(dt.Rows[b][0].ToString());
                }
            }
        }
        using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT DISTINCT [Manufacturer]
                                                        FROM [dbo].[products] WHERE Item LIKE '" + cmbPItem.Text + "'", conn))
        {
            DataTable dt = new DataTable();
            sda.Fill(dt);
            if (dt.Rows.Count != 0)
            {
                cmbPMan.Items.Clear();
                for (int m = 0; m < dt.Rows.Count; m++)
                {
                    cmbPMan.Items.Add(dt.Rows[m][0].ToString());
                }
            }
        }
        using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT DISTINCT [Car]
                                                        FROM [dbo].[products] WHERE Item LIKE '" + cmbPItem.Text + "'", conn))
        {
            DataTable dt = new DataTable();
            sda.Fill(dt);
            if (dt.Rows.Count != 0)
            {
                cmbPCar.Items.Clear();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    cmbPCar.Items.Add(dt.Rows[i][0].ToString());
                }
            }
        }
        using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT DISTINCT [Year]
                                                        FROM [dbo].[products] WHERE Item LIKE '" + cmbPItem.Text + "'", conn))
        {
            DataTable dt = new DataTable();
            sda.Fill(dt);
            if (dt.Rows.Count != 0)
            {
                cmbPYr.Items.Clear();
                for (int y = 0; y < dt.Rows.Count; y++)
                {
                    cmbPYr.Items.Add(dt.Rows[y][0].ToString());
                }
            }
        }
        conn.Close();
    }
}

输出就像这样

enter image description here

当用户点击第二个Combox时,在此示例中为cmbPBrand。它使用重复值填充Combobx。但是,当用户点击另一个Combobox时,不会从cmbPBrand中选择任何条目。这些值不重复。

enter image description here

重复值的另一个例子。

enter image description here

cmbPYr中选择cmbPItem后,点击DISTINCT。它复制CLICK值。

请注意,当用户Combobox第二个Leave时会发生这种情况。我正在为Combobox使用MouseClick个活动。

我还尝试添加MouseDownEnter以及SelectedIndexChangedSELECT DISTINCT Brand,Manufacturer,Car,Year FROM [dbo].[products] WHERE Item LIKE 'BRAKE PADS' 事件。但它仍然重复这些值。

编辑:

使用查询时

BRAKE PADS

例如,cmbPItem.Text为ComboBox

enter image description here

它将查询近675行。

enter image description here

编辑:至于凯文的建议。此代码仅适用于品牌private void cmbProd_Enter(object sender, EventArgs e) { itemValue(cmbPItem.Text); } private void itemValue(string sitem) { getBrand(sitem); } private void getBrand(string sitem) { using (SqlCommand cmd = new SqlCommand(@"SELECT DISTINCT [Brand] FROM [dbo].[products] WHERE Item = @Item")) { cmd.Parameters.Add(new SqlParameter("Item", sitem)); populateBrand(cmbPBrand, cmd); } } private void populateBrand(ComboBox cmb, SqlCommand cmd) { using (SqlConnection conn = new SqlConnection(@"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + "")) { using (SqlDataAdapter sda = new SqlDataAdapter(cmd)) { cmd.Connection = conn; DataTable dt = new DataTable(); sda.Fill(dt); if (dt.Rows.Count != 0) { cmb.Items.Clear(); for (int b = 0; b < dt.Rows.Count; b++) { cmb.Items.Add(dt.Rows[b][0].ToString()); } } conn.Close(); } } } ,但仍显示重复值。

{{1}}

1 个答案:

答案 0 :(得分:1)

我建议从稍微不同的角度解决问题。

首先,肯定应考虑更改要参数化的查询。就像我评论的那样,只要你将原始输入直接放入SQL语句中,就会打开SQL注入攻击的大门。即使它不是基于用户输入,它仍然是一个坏习惯进入。做SQL参数化并不难 - 这只是一行额外的代码。

接下来:重构您的代码。如果我理解正确,您的代码如下:

Event X
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event Y
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event Z
{
    13 or so lines to update Combo Box #1
    13 or so lines to update Combo Box #2
    13 or so lines to update Combo Box #3
    13 or so lines to update Combo Box #4
}
Event ... etc

使用单一责任原则(SRP)进行谷歌搜索并使用它 - 它将帮助您编写更清晰,更易于调试的代码。

什么时候说完了?然后你有一个很好的方法来弄清楚问题是什么:在你的“UpdateBrandCombo()”函数中添加一些调试行 - 在 only 的地方更新Brand组合框(现在,你有一个问题,那些事件中的任何一个都可能正在更新组合框,你真的没有任何好办法搞清楚它在做什么。)

类似的东西:

Event X
{
    UpdateCombosWithSearch(cmbPItem.Text);
}
// ... later on ...
private void UpdateCombosWithSearch(string searchTerm)
{
    UpdateBrandCombo(searchTerm);
    UpdateMfgCombo(searchTerm);
    UpdateCarCombo(searchTerm);
}
private void UpdateBrandCombo(string searchTerm)
{
        SqlCommand sqlCmd = new SqlCommand("select distinct car from dbo.products where Item like @item");
        sqlCmd.Parameters.Add(new SqlParameter("item", searchTerm));
        SetComboBoxUsingQuery(cmbPBrand, sqlCmd);
}
private void SetComboBoxUsingQuery(ComboBox cbx, SqlCommand sqlCmd)
{
    cbx.Items.Clear();
    // code to get a DataTable from the sqlCmd
    // code to read the DataTable and add items to cbx
}

看到美女?你没有重复的代码。您的事件都有一行:UpdateCombosWithSearch()。 UpdateCombosWithSearch只需在需要更新的每个组合框上调用Update。这些函数中的每一个都只生成一个SQL命令并传入哪个框进行更新。唯一具有任何SQL代码的函数是SetComboBoxUsingQuery()函数。

所以现在你可以添加如下内容:

System.Diagnostics.Debug.WriteLine("Event logged by " + (new System.Diagnostics.StackTrace()).ToString());

...其中一个功能 - 这样您就可以确定更新代码的调用位置/时间/方式。