首页 > 解决方案 > 在 C# WinForm 中依赖和动态更改组合框值列表

问题描述

在我的 C# WinForm 中,有两个comboboxes称为cmbTransFirstHelpercmbTransSecondHelper。这些组合框是从数据库中的同一表和同一列填充的。我使用 ExternalDataLoad类从数据库中获取数据,并将 DataTable 类型返回给 WinForm 类。在 winform 的类中调用了两个函数loadFirstHelperloadSecondHelper用于将数据填充到上述组合框,并且在加载表单时调用这些函数。

现在我想要这个,当我在cmbTransFirstHelper组合框中选择一个值时,应该从cmbTransSecondHelper值列表和 v/v 中删除该值。

可能吗 ?我该怎么做?

这是我从数据库中获取数据的 DataLoad 类函数,

public DataTable loadEmployees(string category)
    {

        con.OpenConection();
        SqlDataAdapter sda = con.DataAdapter("select * from employees where employee_category ='"+ category +"'");
        DataTable dt = new DataTable();
        sda.Fill(dt);
        return dt;
        con.CloseConnection();

    }

这些是我的loadFirstHelperloadSecondHelper功能

private void loadFirstHelper()
    {
        dt = dl.loadEmployees("Helper");
        dr = dt.NewRow();
        dr.ItemArray = new object[] { 0, "--Select Helper--" };
        dt.Rows.InsertAt(dr, 0);
        cmbTransFirstHelper.ValueMember = "employee_id";
        cmbTransFirstHelper.DisplayMember = "employee_name";
        cmbTransFirstHelper.DataSource = dt;
    }
    private void loadSecondHelper()
    {
        dt = dl.loadEmployees("Helper");
        dr = dt.NewRow();
        dr.ItemArray = new object[] { 0, "--Select Helper--" };
        dt.Rows.InsertAt(dr, 0);
        cmbTransSecondHelper.ValueMember = "employee_id";
        cmbTransSecondHelper.DisplayMember = "employee_name";
        cmbTransSecondHelper.DataSource = dt;
    }

这就是我在 formLoad 事件中调用上述函数的方式

private void transVehicleINOUT_Load(object sender, EventArgs e)
    {
        this.loadVehicles();
        this.loadDiver();
        this.loadItems();
        this.loadFirstHelper();
        this.loadSecondHelper();
    }

有什么办法可以解决我的问题吗?

标签: c#combobox

解决方案


您可以通过过滤第二个组合框的现有数据源来删除项目。

var original = (DataTable)cmbTransSecondHelper.DataSource;
var selected = (int)cmbTransSecondHelper.SelectedValue;
var filtered = 
    original.AsEnumerable()
            .Where(row => row.Field<int>("employee_id") != selected)
            .CopyToDataTable();

cmbTransSecondHelper.DataSource = filtered;

如果您想在第一个组合框中选择另一个值时返回已删除的值,您可以将原始集合保存在局部变量中并用于过滤。

将动态数据传递给 sql 查询时始终使用 SqlParameters。
如果可能,请尝试为每个查询创建和处理新连接。
也只从数据库加载你真正需要的数据,尽量不要使用SELECT * FROM

在您的特定情况下,我不会仅对两个数据字段使用“重” DataTable。
创建一个类并使用集合将其用作数据源。

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public List<Employee> LoadEmployees(string category)
{
    var query = 
"SELECT employee_id, employee_name FROM employees WHERE employee_category=@category";
    var parameter = new SqlParameter
    {
        ParameterName = "@category",
        SqlDbType = SqlDbType.Varchar,
        Value = category
    };
    var employees = new List<Employee>();
    using (var connection = new SqlConnection(connectionString))
    using (var command = new SqlCommand(query, connection))
    {
        connection.Open();
        command.Parameters.Add(parameter);

        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                var employee = new Employee
                {
                    Id = reader.GetInt32(0),
                    Name = reader.GetString(1)
                };
                employees.Add(employee);
            }
        }

        return employees;
    }
}

然后你可以只有一个函数用所需的数据填充给定的组合框。

private void FillWithHelpers(ComboBox combobox)
{
    var select = new Employee { Id = 0, Name = "--Select Helper--" };
    var all = LoadEmployees("Helper");
    all.Insert(0, select);

    combobox.ValueMember = "Id";
    combobox.DisplayMember = "Name";
    combobox.DataSource = all;
}

然后在 Load 事件处理程序中为两个组合框调用此函数

private void TransVehicleINOUT_Load(object sender, EventArgs e)
{
    this.loadVehicles();
    this.loadDiver();
    this.loadItems();
    this.FillWithHelpers(cmbTransFirstHelper);
    this.FillWithHelpers(cmbTransSecondHelper);
}

SelectionChangeCommitted第一个组合框的事件处理程序中,您可以轻松地过滤掉选定的值。

private void cmbTransFirstHelper_SelectionChangeCommitted(object sender, EventArgs e)
{
    var original = (List<Employee>)cmbTransSecondHelper.DataSource;
    var selectedId = (int)cmbTransSecondHelper.SelectedValue;
    var filtered = 
        original.Where(employee => employee.Id != selectedId).ToList();

    cmbTransSecondHelper.DataSource = filtered;
}

推荐阅读