将下拉列表的选定项设置为 windows 窗体 c# 中匹配的字符串值

Set the selected item of a dropdownlist to the matched string value in windows form c#

我的 windows 表单应用程序中有一个包含制造商名称的下拉列表。编辑给定记录后,我希望用户也能够编辑(更改)制造商。其余值工作正常,我可以轻松地将它们分配到文本框,在那里它们将被编辑并再次存储在数据库中。

我已经从数据库中查询了下拉列表项(需要编辑的制造商名称),现在我想将其显示为下拉列表中的 selected 项。我使用以下代码根据数据库中的 id 查询特定制造商并将其分配给字符串变量 manufacturerName.

DataTable dtMName = Products.SelectByManufacturerId(manufacturerId);
if (dtMName.Rows.Count > 0)
{
    foreach (DataRow item in dtMName.Rows)
    {
        string manufacturerName = item[0].ToString();
    }  
}

调试这段代码时,string manfuacturerName 包含我要在下拉列表中更改的确切制造商名称。现在,我想将此特定项目标记为下拉列表中的 selected 项目。我想将它传递到列表中,以便它可以 select 列表中的这个特定制造商。

到目前为止,我已经尝试了以下代码,但它不起作用。

childEditProduct.cmbManufacturer.SelectedIndex = childEditProduct.cmbManufacturer.FindString(manufacturerName);

注意:我在 childEditProduct 表单加载时将第一项标记为 selectedIndex。我也评论了该代码,但没有任何效果。我的代码有什么问题吗?或者让我尝试一些更有效的方法来解决我的问题。

要解决此问题并避免将来使用更复杂的代码,最好阅读有关 DisplayMemberValueMember 属性的信息。

要使前两个工作正常,只需执行以下操作:

public class Manufacturer
{
    public int Id { get; set; } //Important to have get/set othervise DisplayMember and ValueMember properties will not work
    public string Name { get; set; } //Important to have get/set othervise DisplayMember and ValueMember properties will not work


    public static List<Manufacturer> GetAllManufacturers()
    {
        List<Manufacturer> list = new List<Manufacturer>();

        //Read manufacturers one by one, create object of Manufacturer and then add that object to list

        return list;

    }
}


//This code below set in form constructor or on load

cmbManufacturer.DisplayMember = "Name";
cmbManufacturer.ValueMember = "Id;
cmbManufacturer.DataSource = Manufacturer.GetAllManufacturers();


//And now when you need to select manufacturer by id you do
cmbManufacturer.SelectedValue = 6; //Will select manufacturer which has id 6


//If you have updated your manufacturers in runtime and want to again load everything in combobox just do

cmbManufacturer.DataSource = Manufacturer.GetAllManufacturers();

上面是这两个属性的简单使用,下面我将向您展示更高级的一个。

我们将重写我们的 Manufacturer class 如下:

public class Manufacturer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string City { get; set; }
    public string PersonInCharge { get; set; }
    public string PhoneNumber { get; set; }

    public static List<Tuple<string, Manufacturer>> GetAllManufacturers()
    {
        //This one i will make example with interaction to database

        List<Tuple<string, Manufacturer>> list = new List<Tuple<string, Manufacturer>>();

        using(SqlConnection con = new SqlConnection("SomeSqlString"))
        {
            con.Open();
            using(SqlCommand cmd = new SqlCommand("Select Id, Name, City, Person, Phone from Manufacturers", con))
            {
                SqlDataReader dr = cmd.ExecuteReader();

                while(dr.Read()) //Will read one by one line
                {
                    Manufacturer m = new Manufacturer();
                    m.Id = Convert.ToInt32(dr[0]);
                    m.Name = dr[1].ToString();
                    m.City = dr[2].ToString();
                    m.PersonInCharge = dr[3].ToString();
                    m.PhoneNumber = dr[4].ToString();
                    list.Add(new Tuple<string, Manufacturer>(m.Id, m));
                }
            }
        }
        return list;
    }
}

像这样 class 我们有关于我们制造商的额外信息,但如何显示或存储它?好吧,我们的标签进来了。

Tag is type of object which holds any additional object you want

所以现在我们绑定我们的 DisplayMemberValueMember 就像我们上面所做的那样,但现在我们将首先将我们的列表保存到单独的变量而不是直接绑定数据源:

List<Tuple<string, Manufacturers>> man = Manufacturer.GetAllManufacturers();
cmbManufacturer.DisplayMember = "item1"; //We use item1 and item2 since those are names of variables in Tuple<T>
cmbManufacturer.ValueMember = "item2"; //We use item1 and item2 since those are names of variables in Tuple<T>
cmbManufacturer.DataSource = man;

这样我们分配了 item1m.Name 这是我们制造商的名称 DisplayMember 并分配了 item2Manufacturer class 包含有关我们制造商的所有其他信息(是的,我们可以这样做,因为 ValueMemberobject 的类型)。

现在我们已经填充了组合框,但我们将无法轻松 select 像这样的项目:

cmbManufacturer.SelectedValue = 6; //Will select manufacturer which has id 9

因为我们的 SelectedValue 不代表 int 而是 Manufacturer.

我们可以做的是在表单内创建函数,它将 select 它。

private void SelectManufacturerById(int id)
{
    for(int i = 0; i < cmbManufacturer.Items.Count; i++)
    {
        Manufacturer m = (cmbManufacturer.Items[i] as Tuple<string, Manufacturer>).item2;
        if(m.Id == id)
        {
            cmbManufacturer.SelectedItem = cmbManufacturer.Items[i];
            return;
        }
    }
    // Here throw some message since it couldn't find it 
}

也许你仍然不明白为什么要使用标签 属性 因为它只会让这更难,好吧它不是因为通过 ID 代码 selecting,你可以很容易地通过 Manufacturer class 中的其他值将其更改为 select,您也可以向制造商 class 添加更多代码,例如

public void Update()
{
    using(SqlConnection con = new SqlConnection("SomeSqlString"))
    {
        con.Open();
        using(SqlCommand cmd = new SqlCommand("Update Manufacturers set Id = @id ....", con))
        {
            cmd.Parameters.AddWithValue("@id", m.Id);
            //Assigning other paramterts

            cmd.ExecuteNonQuery();
            //Display message of success
        }
    }
}

然后在带有组合框的表单中执行类似这样的操作

Manufacturer m = cmbManufacturer.SelectedValue as Manufacturer; //We will get currently selected manufacturer inside combobox
m.Name = "Here we change name of it";
m.Update(); //Here we run function inside our class and it will update database and new name

正如我上面提到的,第一个代码将解决您的问题并让您的生活更轻松,但如果您习惯了第二个代码,您将看到更多的可能性。

当我使用以下函数在我的 childForm 加载事件中加载制造商下拉列表时:

private void LoadManufacturers()
{
    cmbManufacturer.Items.Clear();
    DataTable dtManufacturers = DataAccess.Select("select manufacturername from tblmanufacturer order by manufacturername asc");
    foreach (DataRow dr in dtManufacturers.Rows)
    {
        cmbManufacturer.Items.Add(dr[0].ToString());
    }
    //cmbManufacturer.SelectedIndex = 0;
}

在页面加载事件中加载制造商时,我还使用稍后注释掉的代码 cmbManufacturer.SelectedIndex = 0; 指定了下拉列表的选定索引。

完成后,我会在下拉列表的加载事件中重新计算(重新查询)所选制造商(用户想要更新),如下所示:

private void frmChildEditProduct_Load(object sender, EventArgs e)
{
    LoadManufacturers(); // Calling the loadManufacturers function to load all the manufacturers to the dropdown list.

    string manufacturerID = lblManufacturerId.Text;

    DataTable dtMName = Products.SelectByManufacturerId(manufacturerID);
            if (dtMName.Rows.Count > 0)
            {
                foreach (DataRow manufacturer in dtMName.Rows)
                {
                    string manufacturerName = manufacturer[0].ToString();
                    cmbManufacturer.SelectedIndex = Convert.ToInt32(cmbManufacturer.FindStringExact(manufacturerName));
                }
            }
 }

我的问题已经解决了。感谢您在 Whosebug 上对我的支持。