Winforms TextBox keeps value in UserControl

Viewed 40

I am making an app in which there are multiple UserControls stacked onto each other. So the elements go like this: MainForm -> User clicks on a UserControl1 on the MainForm which (UserControl1) has a panel on which there is displayed another UserControl2 with a button. When the user clicks on it, it displays another UserControl3 which is then displayed in the panel beneath the button, where finally the user enters some text in the textbox. I need the data from the textbox in the MainForm so I have MainForm and UserControls connected via EventHandlers and pass my ResponseModel in which there is some dat a that I need to pass to MainForm. The first time this works, an item is created and displayed, after the item there is this "button" (User controls) displayed, in case the user wants to create another one. But then comes the problem when the user types in a different text for a new item, it creates an item with the same text!! Like the textbox was never changed (I have a debugging point set on the constructor to see every time that the textbox is empty). Below is some code and an image, for you to see how this should work. Also when I first delete the item it then doesn't work to create a new item for some reason.

Image of my program

This is how I send the data from the last UserControl:

if (tbx_list_name.Text == "") 
    MessageBox.Show("You can't create new list without a name!", "Can't create new list!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
else
    CreateListTextBoxHandler?.Invoke(this, new ListCreationResponseModel() {
        Code = id, ListName = tbx_list_name.Text
    });

This is how I create the last UserControl which has the textbox:

control.CreateListTextBoxHandler += GetHandlerData;
panel.Controls.Add(control);

And this is how I get the data one stage down (this practice continues through couple more stages back to MainForm):

public void GetHandlerData(object sender, ListCreationResponseModel e)
{
    try
    {
        panel.Controls.Clear();
        CreateListButtonHandler?.Invoke(this, e);
    }
    catch (Exception ex)
    {
        _ = new ErrorHandler(ex);
    }
}
1 Answers

You seem to have a recursion here. GetHandlerData is added to the CreateListTextBoxHandler event (or delegate) and invokes CreateListTextBoxHandler again, which will call GetHandlerData again...?? But tbx_list_name.Text is passed to the model only once at the top level down to all the other calls.

You can fix this by passing a reference to the textbox instead of the text itself. Then you will always be able to retrieve the current text of the textbox.

public class ListCreationResponseModel
{
    private readonly TextBox _listNameTextBox;

    public ListCreationResponseModel(TextBox listNameTextBox)
    {
        _listNameTextBox = listNameTextBox;
    }

    public int Code { get; set; }
    public string ListName => _listNameTextBox .Text;
}

Now, when you retrieve the ListName you don't get a stored value but the actual text of the textbox.

You can create the handler like this:

CreateListTextBoxHandler?.Invoke(this, new ListCreationResponseModel(tbx_list_name) {
    Code = id
});
Related