首先:我的列表填充了客户的对象类型
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();
}
答案 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.Count
后DataSource
保持不变,但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; }
}