Home > other >  Binding TextBox to a Windows Form not working
Binding TextBox to a Windows Form not working

Time:01-23

My environment is:

Windows 11
Windows Form App created by the Windows Forms App template of Visual Studio 2022.

Problem:

I have a simple Windows Form with only a Textbox and a Button. I am trying to update the Textbox text with new data whenever the button is pressed.

The binding works when the Windows Form is loaded. The text "12.34" appears in the Textbox.
But when I click on the button, the Textbox is not updated with the new data. Here is my code:

namespace WatchChart;

public partial class WatchForm:Form
{
    public class BidAsk
    {
        public string? BidString { get; set; }
    }

    public WatchForm()
    {
        InitializeComponent();
    }

    private void MyForm_Load(object sender, EventArgs e)
    {
        var bid = new BidAsk() { BidString = "12.34" };
        bidTextBox.DataBindings.Add(nameof(TextBox.Text), bid, nameof(BidAsk.BidString));
    }

    private void displayButton_Click(object sender, EventArgs e)
    {
        var bidask = new BidAsk();
        bidask.BidString = "23.45";
    }
}

Any help will be greatly appreciated,
Charles

CodePudding user response:

You are creating a new BidAsk (let's call it bidAsk1) on load, and binding to that. Then on the button click, you are creating another BidAsk (bidAsk2) and setting the content. Your textbox is still bound to bidAsk1, not bidAsk2 so it will not be updated.

Try keeping a reference to the bound object:

namespace WatchChart;

public partial class WatchForm:Form
{
    public class BidAsk
    {
        public string? BidString { get; set; }
    }

    private BidAsk bid;

    public WatchForm()
    {
        InitializeComponent();
    }

    private void MyForm_Load(object sender, EventArgs e)
    {
        bid = new BidAsk() { BidString = "12.34" };
        bidTextBox.DataBindings.Add(nameof(TextBox.Text), bid, nameof(BidAsk.BidString));
    }

    private void displayButton_Click(object sender, EventArgs e)
    {
        bid.BidString = "23.45";
    }
}

CodePudding user response:

The first potential issue is that you need the bound variable to be a member of the main form (instead of making a local var inside the methods). The other potential issue is making sure to enable two-way binding. The BidString property should be implemented similar to the BidAsk shown in order to fire a PropertyChange event whenever its value changes.

class BidAsk : INotifyPropertyChanged
{
    string _bidString = string.Empty;
    public string BidString
    {
        get => _bidString;
        set
        {
            if (!Equals(_bidString, value))
            {
                _bidString = value;
                OnPropertyChanged();
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

screenshot


Test

Here's the code I used to test this answer::

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void onl oad(EventArgs e)
    {
        base.OnLoad(e);
        BidAsk = new BidAsk();

        textBoxBid.DataBindings.Add(
            propertyName: nameof(TextBox.Text), 
            dataSource: BidAsk, 
            dataMember: nameof(BidAsk.BidString));

        buttonDisplay.Click  = onClickButtonDisplay;
    }
    BidAsk BidAsk { get; set; }

    private void onClickButtonDisplay(object? sender, EventArgs e)
    {
        // Test string gobbledegook
        var marklar = Guid.NewGuid().ToString().Substring(0, 11);
        BidAsk.BidString = marklar;
    }
}
  • Related