0

Here I'm talking about Windows Forms Application written in C#. Consider a simple model

class Labelled
{
    private string label;
    public string Label
    {
        get { return label; }
        set
        {
            if (label != value)
            {
                string message = String.Format(
                    "Label changed from {0} to {1}",
                    label, value
                );
                MessageBox.Show(message);
                label = value;
            }
        }
    }

    public Labelled(string label)
    {
        this.label = label;
    }
}

class Model
{
    public Labelled SingularLabelled { get; set; }

    public List<Labelled> ListedLabelled { get; set; }

    public Model()
    {
        SingularLabelled = new Labelled("Singular");

        ListedLabelled = new List<Labelled>();

        for (int i = 1; i <= 10; ++i)
            ListedLabelled.Add(new Labelled("Listed " + i.ToString()));
    }
}

We have a simple class Labelled with string property Label and class Model with member SingularLabelled of type Labelled and ListedLabelled which is a list of Labelled's.

Now I want to display the data to the user. Here is my setup:

Main window and data bindings

The main window has a TextBox for displaying SingularLabelled.Label and a DataRepeater from the Visual Basic PowerPacks to display labels of the elements of ListedLabelled. The ItemTemplate of the DataRepeater consists of just a single TextBox.

Let's focus on one way binding, namely I want the underlying data to be updated when the User changes the contents of a text box. The Label property of the Labelled raises a notification in form of a message box, so I can get to know exactly when the data is being updated. Now the arrows represent bindings. Blue arrows stand for data source and the red ones for data members. An instance of Model is created and bound to the modelBindingSource in the constructor of the main window form.

And here we come to a very important thing. I want the data to be updated immediately in sync with what the User is typing, so I made sure that the data source update modes of the data bindings are set to OnPropertyChanged. The generated code that might be of interest here is

this.singularTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.modelBindingSource, "SingularLabelled.Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.listedTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.listedLabelledBindingSource, "Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

And this is working as expected when typing into the text box of SingularLabelled but the text boxes within DataRepeater trigger the update only when they loose focus. I want them to behave like the singular one. Ideal solution would be to do it using the designer. Does anyone know how to do this?

SingularLabelled label update

ListedLabelled label update

Above is a sample of the program working. Notice how SingularLabelled's label is updated every character put in and the members of ListedLabelled get the whole edited chunk updated after the corresponding text box looses focus.

Marcin Kaczmarek
  • 1,063
  • 2
  • 9
  • 20

1 Answers1

1

We were able to overcome this limitation of DataRepeater by simulating the Tab key.

    private void listedTextBox_TextChanged(object sender, EventArgs e)
    {
        //simulate tab key to force databinding
        SendKeys.Send("{TAB}");
        SendKeys.Send("+{TAB}");
    }
Jacob Seleznev
  • 8,013
  • 3
  • 24
  • 34
  • That's an interresting proposition. Nevertheless for now I just dropped the `DataRepeater` and assembled my own control similar to it that doesn't have that problem. – Marcin Kaczmarek Jun 04 '13 at 21:25