Winforms list is not updated when binding data changes

The following shows how my code works. When I press button2, the list is updated, but not when button1 is pressed. Why?

pseudocode http://i44.tinypic.com/mj69oj.gif

Is the problem related to threads? If so, where should I add a (Begin) Invoke call?

It is interesting to note that if I first press button1, and then button2, the data generated by clicking button1 will be shown when button2 is pressed. Thus, it seems that the data created by doFoo is buffered somewhere and then dragged into the list as soon as I press button2.

EDIT:

I tried adding AddNumber to the form code and added an Invoke call when listBox1.InvokeRequired returns true. This solves the problem, but not the most beautiful design. I do not want the GUI to have to “worry” about how to add items to the list of this part of the model.

How can I keep the logic of adding to the list inside the list class while maintaining the change of gui when the list changes?

EDIT 2:

Now that we have confirmed that this is a threading problem, I updated the image to more accurately reflect the design of the actual code I'm working on.

While Lucero's suggestion still solves the problem, I was hoping it didn't require the form to know anything about dll or CDllWrapper.

The model (ListBoxDataBindingSource, etc.) knows nothing about the view at all (lists, buttons, labels, etc.)

+5
4

, , . : . , , , . , , .

: AddNumber() Invoke() ( Control), . .

, : . , , . Control , BindingList, Invoke . , upate , .

:

internal class ListBoxDataBindingSource {
  private readonly Control uiInvokeControl;
  private readonly BindingList<Item> list = new BindingList<Item>();

    public ListBoxDataBindingSource(Control uiInvokeControl) {
      if (uiInvokeControl == null) {
            throw new ArgumentNullException("uiInvokeControl");
      }
        this.uiInvokeControl = uiInvokeControl;
        CDIIWrapper.setFP(AddNumber);
    }

    public void AddNumber(int num) {
      Item item = new Item(num.ToString());
        if (uiInvokeControl.InvokeRequired) {
            uiInvokeControl.Invoke(list.Add, item);
        } else {
            list.Add(item);
        }
    }

    private BindingList<Item> List {
        get {
            return list;
        }
    }
}
+2
+1

, setFP lbDataBindingSource.AddNumber, , lbDataBindingSource.AddNumber .

void MyForm_Load(object sender, EventArgs e)
{
    //...

    cdll.setFP(FPCallback);
}

private void FPCallback(int num)
{
    lbDataBindingSoruce.AddNumber(num);
}
0

, ,

Lucero : Invoke

:

listBox.Invoke((Action)delegate
{
    MyViewModel.AddItem(param1, param2);
});
0

All Articles