C# 更新数据绑定 ComboBox

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/504551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:56:19  来源:igfitidea点击:

Updating a databound ComboBox

c#.netcomboboxrefresh

提问by Dan Vogel

I am having virtually the same problem as this:

我遇到了与此几乎相同的问题:

C# Update combobox bound to generic list

C# 更新组合框绑定到通用列表

However, I am trying to change the displayed strings; not add, remove, or sort. I have tried the BindingList solution provided in the referenced question, but it has not helped. I can see the combobox's DataSource property is correctly updated as I edit the items, but the contents displayed in the combobox are not those in the DataSource property.

但是,我正在尝试更改显示的字符串;不添加、删除或排序。我已经尝试了参考问题中提供的 BindingList 解决方案,但没有帮助。我可以看到组合框的 DataSource 属性在我编辑项目时正确更新,但组合框中显示的内容不是 DataSource 属性中的内容。

my code looks as follows:

我的代码如下所示:

mSearchComboData = new List<SearchData>();
mSearchComboData.Add(new SearchData("", StringTable.PatientID));
mSearchComboData.Add(new SearchData("", StringTable.LastName));
mSearchComboData.Add(new SearchData("", StringTable.LastPhysician));
mSearchComboData.Add(new SearchData("", StringTable.LastExamDate));

mBindingList = new BindingList<SearchData>(mSearchComboData);

SearchComboBox.Items.Clear();
SearchComboBox.DataSource = mBindingList;
SearchComboBox.ValueMember = "Value";
SearchComboBox.DisplayMember = "Display";

...

When I try to update the content I do the following:

当我尝试更新内容时,我会执行以下操作:

int idx = SearchComboBox.SelectedIndex;
mBindingList[idx].Display = value;
SearchComboBox.Refresh();

EDIT::

编辑::

RefreshItems seems to be a private method. I just get the error message:

RefreshItems 似乎是一个私有方法。我只收到错误消息:

"'System.Windows.Forms.ListControl.RefreshItems()' is inaccessible due to its protection level"

“'System.Windows.Forms.ListControl.RefreshItems()'由于其保护级别而无法访问”

ResetBindings has no effect.

ResetBindings 无效。

采纳答案by BFree

If you were to change the entire object, meaning your entire SearchData object, then the bindinglist would have knowledge of this change, and therefore the correct events would internaly get fired, and the combobox would update. HOWEVER, since you're only updating one property, the bindinglist has no idea that something has changed.

如果您要更改整个对象,即您的整个 SearchData 对象,则 bindinglist 将知道此更改,因此将在内部触发正确的事件,并且组合框将更新。但是,由于您只更新一个属性,因此 bindinglist 不知道某些内容已更改。

What you need to do is have your SearchData class implement INotifyPropertyChanged. Here's a quick sample I wrote to demonstrate:

您需要做的是让 SearchData 类实现 INotifyPropertyChanged。这是我写的一个快速示例来演示:

public class Dude : INotifyPropertyChanged
    {
        private string name;
        private int age;

        public int Age
        {
            get { return this.Age; }
            set
            {
                this.age = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("Age"));
                }
            }
        }
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;


    }

And here's some code to test:

这是一些要测试的代码:

        private void button1_Click(object sender, EventArgs e)
        {
            //Populate the list and binding list with some random data  
            List<Dude> dudes = new List<Dude>();
            dudes.Add(new Dude { Name = "Alex", Age = 27 });
            dudes.Add(new Dude { Name = "Mike", Age = 37 });
            dudes.Add(new Dude { Name = "Bob", Age = 21 });
            dudes.Add(new Dude { Name = "Joe", Age = 22 });

            this.bindingList = new BindingList<Dude>(dudes);
            this.comboBox1.DataSource = bindingList;
            this.comboBox1.DisplayMember = "Name";
            this.comboBox1.ValueMember = "Age";

        }


    private void button3_Click(object sender, EventArgs e)
    {
        //change selected index to some random garbage
        this.bindingList[this.comboBox1.SelectedIndex].Name = "Whatever";
    }

Since my class now implements INotifyPropertyChanged, the binding list gets "notified" when something changes, and all this will thus work.

由于我的类现在实现了 INotifyPropertyChanged,因此当发生变化时绑定列表会得到“通知”,所有这些都将起作用。

回答by YonahW

instead of SearchComboBox.Refresh();

代替 SearchComboBox.Refresh();

try SearchComboBox.RefreshItems();

尝试 SearchComboBox.RefreshItems();

or SearchComboBox.ResetBindings();

或者 SearchComboBox.ResetBindings();

I think it is really the latter that you need.

我认为你真正需要的是后者。

You can access the documentation for it's members here.

您可以在此处访问其成员的文档。

回答by BrianB

This is an old post but this may be useful.

这是一个旧帖子,但这可能有用。

I have just been looking at the same problem and have found that if you call ResetItemon the BindingListobject, with the changed Items position, it internal raises the Itemchangednotification event for you causing the list to update.

我刚才一直在看同样的问题,已经发现,如果你调用ResetItemBindingList的对象,与更改的项目位置,它的内部提高了Itemchanged对您通知事件造成的列表更新。

int idx = SearchComboBox.SelectedIndex;
mBindingList[idx].Display = value;

mBindingList.ResetItem(idx); //raise Item changed event to update the list display