简体   繁体   English

具有相同数据源的多个组合框 (C#)

[英]Multiple Combo Boxes With The Same Data Source (C#)


UPDATE: This is now resolved, see answer below.更新:现在已解决,请参阅下面的答案。


On one of my forms (in a Windows Forms application) I have 3 Combo Boxes.在我的一个表单(在 Windows 表单应用程序中)上,我有 3 个组合框。 These combo boxes need to display a list of prices (In text, with an integer back-end value).这些组合框需要显示价格列表(在文本中,带有整数后端值)。

All of these combo boxes are using the same data source (A List<> of type TSPrice, with ValueMember set to Price and DisplayMember set to Description).所有这些组合框都使用相同的数据源(TSPrice 类型的 List<>,ValueMember 设置为 Price,DisplayMember 设置为 Description)。

My problem is this... Everytime I choose a price option from one of the dropdowns, they ALL change to the same value... Is this something to do with them all being bound to the same data source?我的问题是...每次我从下拉列表中选择一个价格选项时,它们都会更改为相同的值...这与它们都绑定到相同的数据源有关吗?

Here is how I am binding them:这是我如何绑定它们:

var priceList = new List<TSPrice>
                    {
                        new TSPrice(0, ""),
                        new TSPrice(0, "Half Day"),
                        new TSPrice(0, "Full Day"),
                        new TSPrice(0, "1 + Half"),
                        new TSPrice(0, "2 Days"),
                        new TSPrice(0, "Formal Quote Required")
                    };

objInsuredPrice.DataSource = priceList;
objTPPrice.DataSource = priceList;
objProvSum.DataSource = priceList;

objInsuredPrice.ValueMember = "Price";
objTPPrice.ValueMember = "Price";
objProvSum.ValueMember = "Price";

objInsuredPrice.DisplayMember = "Description";
objTPPrice.DisplayMember = "Description";
objProvSum.DisplayMember = "Description";

objInsuredPrice.SelectedIndex = 0;
objTPPrice.SelectedIndex = 0;
objProvSum.SelectedIndex = 0;

//objInsuredPrice.DataSource      = objTPPrice.DataSource     = objProvSum.DataSource     = priceList;
//objInsuredPrice.ValueMember     = objTPPrice.ValueMember    = objProvSum.ValueMember    = "Price";
//objInsuredPrice.DisplayMember   = objTPPrice.DisplayMember  = objProvSum.DisplayMember  = "Description";
//objInsuredPrice.SelectedIndex   = objTPPrice.SelectedIndex  = objProvSum.SelectedIndex  = 0;

Edit: The issue was that they were all being bound to the same DataSource as confirmed by Saurabh.编辑:问题是他们都被绑定到 Saurabh 确认的同一个数据源。 This is how I solved it.我就是这样解决的。

var priceList = new List<TSPrice>
                    {
                        new TSPrice(0, ""),
                        new TSPrice(1, "Half Day"),
                        new TSPrice(2, "Full Day"),
                        new TSPrice(3, "1 + Half"),
                        new TSPrice(4, "2 Days"),
                        new TSPrice(5, "Formal Quote Required")
                    };

var insuredList = new TSPrice[5];
var TPList = new TSPrice[5];
var provList = new TSPrice[5];

priceList.CopyTo(insuredList);
priceList.CopyTo(TPList);
priceList.CopyTo(provList);

objInsuredPrice.DataSource = insuredList;
objTPPrice.DataSource = TPList;
objProvSum.DataSource = provList;

objInsuredPrice.ValueMember     = objTPPrice.ValueMember    = objProvSum.ValueMember    = "Price";
objInsuredPrice.DisplayMember   = objTPPrice.DisplayMember  = objProvSum.DisplayMember  = "Description";
objInsuredPrice.SelectedIndex   = objTPPrice.SelectedIndex  = objProvSum.SelectedIndex  = 0;

probably you could also try this solution, just assign a new Context to the 2nd combo box:也许你也可以尝试这个解决方案,只需为第二个组合框分配一个新的上下文:

                combobox1.DataSource = results;
                combobox1.DisplayMember = "DisplayValue";
                combobox1.ValueMember = "Value";

                combobox2.BindingContext = new BindingContext();   //create a new context
                combobox2.DataSource = results;
                combobox2.DisplayMember = "DisplayValue";
                combobox2.ValueMember = "Value";

Thank you谢谢

I don't see why this should be so hard... you can just link them to clones of the same data source... that solves the problem.我不明白为什么这会这么难......你可以将它们链接到相同数据源的克隆......解决问题。 All you need to do is你需要做的就是

objInsuredPrice.DataSource = new List<TSPrice>(priceList);
objTPPrice.DataSource = new List<TSPrice>(priceList);
objProvSum.DataSource = new List<TSPrice>(priceList);

Incidentally, this is exactly what VVS' code does.顺便说一下,这正是 VVS 代码所做的。

Still, weird behaviour... that just has to be a bug, imo.不过,奇怪的行为......这只是必须有一个bug,海事组织。

I know you didn't ask for it but may I suggest you to refactor your final code a little bit :-)我知道你没有要求它,但我可以建议你稍微重构一下你的最终代码:-)

private List<TSPrice> GetPriceList()
{
  return new List<TSPrice>
             {
               new TSPrice(0, ""),
               new TSPrice(0, "Half Day"),
               new TSPrice(0, "Full Day"),
               new TSPrice(0, "1 + Half"),
               new TSPrice(0, "2 Days"),
               new TSPrice(0, "Formal Quote Required")
             };
}

private void BindPriceList(ComboBox comboBox, List<TSPrice> priceList)
{
  comboBox.DataSource = priceList();
  comboBox.ValueMember = "Price";
  comboBox.DisplayMember = "Description";
  comboBox.SelectedIndex = 0;
}    

BindPriceList(objInsuredPrice, GetPriceList());
BindPriceList(objTPPrice, GetPriceList());
BindPriceList(objProvSum, GetPriceList());

Yes , absolutely you are correct since you are binding to the same source , so selecting in one will be applied to the rest of the combox是的,绝对正确,因为您绑定到相同的源,因此选择其中之一将应用于组合框的其余部分

for overcoming to this problem , you need to manually remove the other combobox handler in a slectedindex changed event then set selected index and then again add handlers to put in code , just see below为了克服这个问题,您需要在 slectedindex changed 事件中手动删除其他组合框处理程序,然后设置选定的索引,然后再次添加处理程序以放入代码,如下所示

    ComboBox c1 = new ComboBox();
        ComboBox c2 = new ComboBox();

        c1.SelectedIndexChanged += new EventHandler(c1_SelectedIndexChanged);


        c2.SelectedIndexChanged += new EventHandler(c2_SelectedIndexChanged);

    void c2_SelectedIndexChanged(object sender, EventArgs e)
    {
        c1.SelectedIndexChanged -= c1_SelectedIndexChanged;
        c2.SelectedIndex = 2;
        c1.SelectedIndexChanged += c1_SelectedIndexChanged;

    }

    void c1_SelectedIndexChanged(object sender, EventArgs e)
    {
        c2.SelectedIndexChanged -= c2_SelectedIndexChanged;
        c1.SelectedIndex = 2;
        c2.SelectedIndexChanged += c2_SelectedIndexChanged;
    }

Beth Massi has written an article explaining this issue and the correct solution: https://web.archive.org/web/20190114100843/https://blogs.msdn.microsoft.com/bethmassi/2007/09/19/binding-multiple-combo-boxes-to-the-same-data-source/ Beth Massi 写了一篇文章解释这个问题和正确的解决方案: https : //web.archive.org/web/20190114100843/https : //blogs.msdn.microsoft.com/bethmassi/2007/09/19/binding-多个组合框到同一数据源/

She has a series of other videos on Databinding that she links to, also.她还有一系列其他关于数据绑定的视频,她也链接到这些视频。

I've read the previous answers and can confirm that, sadly, none of them worked when I tried them.我已经阅读了之前的答案并且可以确认,遗憾的是,当我尝试它们时,它们都不起作用。

Creating a new BindingContext on a combobox just seems to break it.在组合框上创建一个新的 BindingContext 似乎会破坏它。 I suggest doing as Beth explains: make a completely new BindingSource setup.我建议像 Beth 解释的那样做:做一个全新的 BindingSource 设置。

This works for me and I don't need to copy the source.这对我有用,我不需要复制源代码。

List<string> days = GetDays();
List<string> months = GetMonths();
List<string> years = GetYears();

Son1DDLDay.DataSource = days;
Son1DDLDay.DataBind();
Son1DDLMonth.DataSource = months;
Son1DDLMonth.DataBind();
Son1DDLYear.DataSource = years;
Son1DDLYear.DataBind();

Son2DDLDay.DataSource = days;
Son2DDLDay.DataBind();
Son2DDLMonth.DataSource = months;
Son2DDLMonth.DataBind();
Son2DDLYear.DataSource = years;
Son2DDLYear.DataBind();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM