简体   繁体   中英

Winforms Two-Way Databinding: Force to Update the Field

I am hoping to get some pointers on what I am missing in my code.
I have a text box bound to a object property that is an item in the list, and that value doesnt update on the form if I request another item in the list.

To illustrate with example below:
txtGain value is populated after openJSONRequestFileToolStripMenuItem_Click fuction
Once I select something different in cmbSignals combobox, I expect the txtGain value to become updated since SelectedChannel is updated as well, which in turn updates the selectedindex but it doesn't happen.

Basically I want to have my txtGain value updated based on what I select in the cmbSignals. Obviously the binding is there so that I can modify the value in the text box and have it be updated in the property its bound to.

I suspect that I have to somehow force update the bindings but not sure how to do that. Any help would be appreciated.

public partial class MainForm : Form
{
    private MyData req;  

    public MainForm()
    {
        InitializeComponent();

        cmbSignals.DisplayMember = "Name";
        cmbSignals.ValueMember = "Value";
    }

    private void openJSONRequestFileToolStripMenuItem_Click(object sender, EventArgs e)  
    {
        string text = File.ReadAllText("sample.json");    
        req = new MyData(JsonConvert.DeserializeObject<SerializedRequest>(text));  
        cmbSignals.DataSource = req.SignalNames;  
        cmbSignals.SelectedValue = req.SelectedChannel;     
        SetBindings();
    }

    private void SetBindings()
    {
        txtGain.DataBindings.Add(new Binding("Text", req, "Gain"));
    }

    private void cmbSignals_SelectedValueChanged(object sender, EventArgs e)
    {
        req.SelectedChannel = Convert.ToInt32(cmbSignals.SelectedValue);
    }
}




public class MyData : INotifyPropertyChanged
{
    private SerializedRequest Data = new SerializedRequest();
    private int selectedIndex = 0;

    public int SelectedChannel
    {
        get
        {
            return selectedIndex + 1;
        }
        set
        {
            this.selectedIndex = value - 1;
        }
    }

    public string Gain
    {
        get
        {
            return Data.signals[selectedIndex].gain;
        }
        set
        {
            Data.signals[selectedIndex].gain = value;
            OnPropertyChanged("Gain");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    public List<SignalsCmbItem>SignalNames
    {

        get
        {
            List<SignalsCmbItem>channels = new List<SignalsCmbItem>();
            for(int i = 0; i<Data.signals.Count;i++)
            {
                channels.Add(new SignalsCmbItem { Value = i + 1, Name = i+1 + " - " + Data.signals[i].label });
            }
            return channels;
        }
    }
}

Pretty annoying "feature", isn't it?.

But no worries, to get around this, add one line of code inside your cmbSignals_SelectedValueChanged(sender, e) method, after you change value of req.SelectedChannel .

txtGain.BindingContext = new BindingContext();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM