ComboBox DataSource动态更改

时间:2018-02-08 17:40:32

标签: c# winforms combobox

首先:我的列表填充了客户的对象类型

List<Customer> Customers = new List<Customer>();

第二:我有2个 ComboBox ,一个用于客户名称,另一个用于客户电话。并将数据源设置为客户列表。

CustomersPhone_ComBx.DataSource = Customers.Select(Customer => Customer.Phone).ToList();
CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();

第三:当用户更改手机组合框中的所选项目时,我想过滤名称组合框中的名称,这些名称与选择的电话号码相同。 (因为它可能是注册了多个名称的电话号码)。我有这个代码

private void CustomersPhone_ComBx_Leave(object sender, EventArgs e)
{
    if (CustomersPhone_ComBx.Text != "")
         CustomersName_ComBx.DataSource = Customers.Where(Customer => Customer.Phone == CustomersPhone_ComBx.Text).Select(Customer => Customer.Name).ToList();
    else
         CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();
}

但是,当我测试它并更改手机组合框中的所选项目名称组合框时,没有任何更改。

更新1

第四:如果我使用foreach,它可以像下面的代码一样正常工作,但不能使用 DataSource

private void CustomersPhone_ComBx_SelectedIndexChanged(object sender, EventArgs e)
{
    List<Customer> FilteredCustomers = Customers
                       .Where(Customer => Customer.Phone == CustomersPhone_ComBx.Text).ToList();

    foreach (Customer C in FilteredCustomers)
        CustomersName_ComBx.Items.Add(C.Name);
}

更新2

2 ComboBox的这些属性,它们是相同的。

        // CustomersName_ComBx
        // 
        this.CustomersName_ComBx.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
        this.CustomersName_ComBx.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
        this.CustomersName_ComBx.Dock = System.Windows.Forms.DockStyle.Fill;
        this.CustomersName_ComBx.Font = new System.Drawing.Font("Janna LT", 12F, System.Drawing.FontStyle.Bold);
        this.CustomersName_ComBx.FormattingEnabled = true;
        this.CustomersName_ComBx.Location = new System.Drawing.Point(0, 65);
        this.CustomersName_ComBx.Margin = new System.Windows.Forms.Padding(0, 7, 0, 0);
        this.CustomersName_ComBx.Name = "CustomersName_ComBx";
        this.CustomersName_ComBx.Size = new System.Drawing.Size(583, 46);
        this.CustomersName_ComBx.Sorted = true;
        this.CustomersName_ComBx.TabIndex = 52;
        // 
        // CustomersPhone_ComBx
        // 
        this.CustomersPhone_ComBx.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
        this.CustomersPhone_ComBx.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
        this.CustomersPhone_ComBx.Dock = System.Windows.Forms.DockStyle.Fill;
        this.CustomersPhone_ComBx.Font = new System.Drawing.Font("Janna LT", 12F, System.Drawing.FontStyle.Bold);
        this.CustomersPhone_ComBx.FormattingEnabled = true;
        this.CustomersPhone_ComBx.Location = new System.Drawing.Point(0, 7);
        this.CustomersPhone_ComBx.Margin = new System.Windows.Forms.Padding(0, 7, 0, 0);
        this.CustomersPhone_ComBx.Name = "CustomersPhone_ComBx";
        this.CustomersPhone_ComBx.Size = new System.Drawing.Size(583, 46);
        this.CustomersPhone_ComBx.Sorted = true;
        this.CustomersPhone_ComBx.TabIndex = 51;
        this.CustomersPhone_ComBx.SelectedIndexChanged += new System.EventHandler(this.CustomersPhone_ComBx_SelectedIndexChanged);

名为 NewReceipt_Delivery_Form 的表格,以及我如何展示它。

NewReceipt_Delivery_Form NewReceipt_Delivery_Form = new NewReceipt_Delivery_Form();
NewReceipt_Delivery_Form.ChangeUI();
NewReceipt_Delivery_Form.ShowDialog();

ChangeUI 方法

private List<Customer> Customers = new List<Customer>();
public void ChangeUI()
{
    OleDbCommand SelectCustomersCMD = new OleDbCommand("SELECT * FROM Customers ORDER BY [ID] ASC", Program.GeneralConnection);
    OleDbDataReader SelectCustomersREAD = SelectCustomersCMD.ExecuteReader();
    while (SelectCustomersREAD.Read())
    {
        Customer Customer = new Customer();
        Customer.ID = Convert.ToInt32(SelectCustomersREAD[0].ToString());
        /* And so on. */
        Customers.Add(Customer);
    }
    SelectCustomersREAD.Close();
    CustomersPhone_ComBx.DataSource = Customers.Select(Customer => Customer.Phone).ToList();
    CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();
    CustomersPhone_ComBx.SelectedIndex = -1;
    CustomersName_ComBx.SelectedIndex = -1;
}

SelectedIndexChanged 事件为Aleksandar's answer

private void CustomersPhone_ComBx_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedPhone = (string)CustomersPhone_ComBx.SelectedItem;
    if (!String.IsNullOrEmpty(selectedPhone))
        CustomersName_ComBx.DataSource = Customers.Where(Customer => Customer.Phone == selectedPhone).Select(Customer => Customer.Name).ToList();
    else
        CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();
}

2 个答案:

答案 0 :(得分:2)

有关组合框属性的新信息,我终于能够重现你的问题。似乎Sorted属性导致了这个问题:

this.CustomersName_ComBx.Sorted = true;

解决方法是将其设置为false

this.CustomersName_ComBx.Sorted = false;

要让显示屏仍然有序,只需在初始化OrderBy时使用DataSource

CustomersPhone_ComBx.DataSource = Customers.Select(Customer => Customer.Phone)
                                           .OrderBy(x=>x).Distinct().ToList();
CustomersName_ComBx.DataSource  = Customers.Select(Customer => Customer.Name)
                                           .OrderBy(x => x).ToList();

A(某种解释)可以在属性Sorted

的文档中找到

在备注部分中说:

  

此属性指定ComboBox是否将现有条目和添加新条目排序到列表中的适当的排序位置。您可以使用此属性自动对ComboBox中的项目进行排序。当项目添加到已排序的ComboBox时,项目将移动到已排序列表中的相应位置。

我想当你改变DataSource时,新元素只是放在旧元素的位置上。但实际的DataSource现在有更少的元素。您可以在调试器中进行检查。分配过滤后的集合后,DataSource的计数会减少!

我的第二个猜测是,如果您设置Sorted = true,它实际上会在初始初始化后忽略DataSource集合,从此刻开始它只显示Items集合中的内容。调试器显示已分配过滤的Items.CountDataSource保持不变,但DataSource.Count已更改。这似乎是一种模棱两可的状态。 您无法修改Items集合,因为ComboBox是数据绑定但您无法显示DataSource,因为Sorted设置为true。实际上这些评论说:

  

尝试在数据绑定控件上设置Sorted属性会引发ArgumentException。您必须使用基础数据模型对数据进行排序。

但它没有说明在之前绑定时会发生什么?

答案 1 :(得分:0)

这是适用于我的解决方案,唯一的区别是我使用了CustomersPhone_ComBx.SelectedItem而不是其文本属性。

 public partial class Form1 : Form
 {
    public List<Customer> Customers { get; set; } = new List<Customer>
    {
        new Customer
        {
            Name = "John",
            Phone = "123"
        },
        new Customer
        {
            Name = "Mary",
            Phone = "123"
        },
        new Customer
        {
            Name = "Peter",
            Phone = "555"
        },
        new Customer
        {
            Name = "George",
            Phone = "222"
        },
        new Customer
        {
            Name = "Christine",
            Phone = "555"
        }
    };

    public Form1()
    {
        InitializeComponent();
        CustomersPhone_ComBx.DataSource = Customers.Select(Customer => Customer.Phone).ToList();
        CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();
    }

    private void CustomersPhone_ComBx_SelectedIndexChanged(object sender, EventArgs e)
    {
        string selectedPhone = (string) CustomersPhone_ComBx.SelectedItem;
        if (!String.IsNullOrEmpty(selectedPhone))
            CustomersName_ComBx.DataSource = Customers.Where(Customer => Customer.Phone == selectedPhone).Select(Customer => Customer.Name).ToList();
        else
            CustomersName_ComBx.DataSource = Customers.Select(Customer => Customer.Name).ToList();
    }
}

public class Customer
{
    public string Name { get; set; }
    public string Phone { get; set; }
}