简体   繁体   English

具有两种方式 DataBinding 的 Winforms 文本框无法正常工作

[英]Winforms Textbox with two way DataBinding not working as it should be

Winforms has two Textboxes. Winforms 有两个文本框。 textBox2 is binded to a property Unit. textBox2绑定到属性 Unit。 I wish that any changes made to Unit or textBox2 will automatically update textBox2 or Unit respectively.我希望对 Unit 或textBox2所做的任何更改都会分别自动更新textBox2或 Unit。 But it does not.但事实并非如此。 Here are three versions of the code for a Winform.以下是 Winform 代码的三个版本。

Version one set data binding, hope it will have two ways auto update but does not work版本一设置数据绑定,希望有两种方式自动更新但是不行

public partial class Receiver : Form, INotifyPropertyChanged
{         

    private int unit=0;
    public int Unit
    {
        get { return unit; }
        set
        {
            if (value != unit)
            {
                unit = value;                                          
            }
        }
    }

    public Receiver()
    {
        InitializeComponent();            
        textBox2.DataBindings.Add("Text", Unit, "Unit");
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {   
        //textBox1 change makes Unit change, 
        //I wish the change will be displayed in textBox2 automatically
        Unit = Convert.ToInt32(textBox1.Text);
    }        
}

Version two with event handler, hard code to update textBox2 with the event handler带有事件处理程序的版本 2 ,使用事件处理程序更新textBox2的硬代码

but change textBox2 still will not update Unit automatically但更改textBox2仍然不会自动更新 Unit

public partial class Receiver : Form, INotifyPropertyChanged
{ 
    public event PropertyChangedEventHandler PropertyChanged;

    private int unit=0;
    public int Unit
    {
        get { return unit; }
        set
        {
            if (value != unit)
            {
                unit = value;                       
                if (PropertyChanged != null)
                {
                   PropertyChanged(this, new PropertyChangedEventArgs(info));
                }  
            }
        }
    }

    public Receiver()
    {
        InitializeComponent();            
        textBox2.DataBindings.Add("Text", this.Unit, "Unit", false, 
                                                 DataSourceUpdateMode.OnPropertyChanged);
        PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);

    }    

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Unit = Convert.ToInt32(textBox1.Text);
    }


    private void OnPropertyChanged(object sender, EventArgs e)
    {  
        //this actually is hard coded to update textBox2, binding does no help
        textBox2.Text = Unit.ToString();
    }
}

Version three why use event handler, we can simply do this way.版本三为什么使用事件处理程序,我们可以简单地这样做。

public partial class Receiver : Form, INotifyPropertyChanged
{ 
    private int unit=0;
    public int Unit
    {
        get { return unit; }
        set
        {
            if (value != unit)
            {
                unit = value;   
                textBox2.text = unit.toString();                          
            }
        }
    }

    public Receiver()
    {
        InitializeComponent();            
        textBox2.DataBindings.Add("Text", Unit, "Unit");
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Unit = Convert.ToInt32(textBox1.Text);           
    }   

    private void textBox2_TextChanged(object sender, EventArgs e)
    {
        Unit = Convert.ToInt32(textBox2.Text);           
    } 
}

} }

Version two and Version three have a problem, any changes to textbox1 will cause update in textbox2 .版本二版本三有问题,对 textbox1 的任何更改都会导致textbox1 textbox2 That will cause a lot of CPU cycle.这将导致大量的 CPU 周期。 The best way is when the mouse focus leaves textBox1 then do the update.最好的方法是当鼠标焦点离开textBox1然后进行更新。 So how to do it?那么该怎么做呢?

The problem in your code is at line:您的代码中的问题在于:

textBox2.DataBindings.Add("Text", Unit, "Unit");

You should replace the data source by the instance that holds that property not the property itself, and here you should also specify the data source update mode set it to DataSourceUpdateMode.OnPropertyChanged .您应该将数据源替换为包含该属性而不是属性本身的实例,并且您还应该在此处指定数据源更新模式,将其设置为DataSourceUpdateMode.OnPropertyChanged So:所以:

textBox2.DataBindings.Add("Text", this, "Unit", false, DataSourceUpdateMode.OnPropertyChanged);

//test using the second or the third approach:
Unit = 15;//now the textBox2.Text equals to 15 too.

textBox2.Text = 12;//now Unit equals 12 too

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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