C # DataBinding - automatically writing a changed property to a label or text field

I read some about DataBinding, mostly complex things like SQL or any XAML and stuff. All I want my program to do is that if the "value" of a variable changes, just write it in a text box or shortcut. (using WindowsForms)

So far I have had:

namespace DataBinding_Test { public partial class Form1 : Form { BindingSource bs = new BindingSource(); Class1 test = new Class1(); public Form1() { InitializeComponent(); test.name = "Hello"; bs.DataSource = test; label1.DataBindings.Add(new Binding("Text", bs, "name", false, DataSourceUpdateMode.OnPropertyChanged)); } private void button1_Click(object sender, EventArgs e) { test.name = textBox1.Text; } } } 

Class1 simply has a public property name. When launched, lable1 will show my "Hello" line. Then, when you click the button, the name of the property changes. When debugging, I saw that the actual DataSource from "bs" contains the new property value, but the label will not show anything ...

Is there any real way to do this?

Rear panel: The RS232 data sensor will be periodically polled. If the value of one sensor changes, I want to show it in a shortcut or text box. Now the backroundthreaded timer will need calls and materials to access the GUI stream; thought it would be easier with data binding, but didn't seem to look: P

Thank you all, great site, great job! :)

+4
source share
5 answers

Another way to make things work without implementing INotifyPropertyChanged

 class Class1 { private string name; public string Name { get { return name; } set { //Check if you are assigning the same value. Depends on your business logic //here is the simplest check if (Equals(name, value)) return; name = value; OnNameChanged(); } public event EventHandler NameChanged; protected virtual void OnNameChanged() { var handler = NameChanged; if (handler != null) handler(this, EventArgs.Empty); } } } 

The trick is to have an event with the name, the combined name of the property and the suffix Changed , and raise it whenever the value of your property changes.

+3
source

For your code to work, you must implement the INotifyPropertyChanged interface in your associated class. Without this, your binding simply does not know when the change occurs. There you must implement the logic according to which you will notify your subscribers that when something has changed in your class (part of the setter) and what has changed (PropertyChangedEventArgs). See an example for your class:

 class Class1: INotifyPropertyChanged { private string name = ""; public string Name { get { return name; } set { name = value; NotifyPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged() { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } 

And change the property name from "name" to "Name" in your binding:

 label1.DataBindings.Add(new Binding("Text", bs, "Name", false, DataSourceUpdateMode.OnPropertyChanged)); 
+2
source
 // create winforms project on form1 drag a textbox (testbox1) // and a button (button1) with a button click event handler // this updates the textbox when the button is clicked using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication3 { public partial class Form1 : Form { MyClass Myobj = new MyClass(); public Form1() { InitializeComponent(); /* propertyname, datasource, datamember */ textBox1.DataBindings.Add("Text", Myobj, "Unit"); } public class MyClass : INotifyPropertyChanged { private int unit = 3; /* property change event */ public event PropertyChangedEventHandler PropertyChanged; public int Unit { get { return this.unit; } set { if (value != this.unit) { this.unit = value; NotifyPropertyChanged("Unit"); } } } private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } private void button1_Click(object sender, EventArgs e) { Myobj.Unit += 4; } } } 
0
source

I created an extension method for this that I would like to provide

Using

 private void Form1_Load(object sender, EventArgs e) { ResultLabel.Bind(NameTextBox); WarningLabel.Bind(NameTextBox,i => i.Length == 0 ? "field required!" : ""); SendButton.Bind(NameTextBox, i => SendButton.Enabled = !(i.Length == 0)); } 

Extension

 public static class Extention { public static void Bind(this Control owner, Control dataSource) { List<EventInfo> fields = dataSource.GetType().GetEvents().ToList(); int index = fields.FindIndex(item => item.Name == "TextChanged"); if (index >= 0) { Control sender = dataSource as Control; owner.Text = dataSource.Text; dataSource.TextChanged += delegate (Object o, EventArgs e) { owner.Text = sender.Text; }; } } public static void Bind(this Control owner, Control dataSource, Func<string,string> onChange) { List<EventInfo> fields = dataSource.GetType().GetEvents().ToList(); int index = fields.FindIndex(item => item.Name == "TextChanged"); if (index >= 0) { Control sender = dataSource as Control; owner.Text = onChange(sender.Text); dataSource.TextChanged += delegate (Object o, EventArgs e) { owner.Text = onChange(sender.Text); }; } } public static void Bind(this Control owner, Control dataSource, Action<string> onChange) { List<EventInfo> fields = dataSource.GetType().GetEvents().ToList(); int index = fields.FindIndex(item => item.Name == "TextChanged"); if (index >= 0) { Control sender = dataSource as Control; onChange(sender.Text); dataSource.TextChanged += delegate (Object o, EventArgs e) { onChange(sender.Text); }; } } } 
0
source

I'm not sure if this is what you want, but you can write whatever you specify in the text box or label using the control.Text property.

 textBox1.Text ="Some other Text" 

or

 string variable = "Hello 2"; textBox1.Text = variable; 

Why do you want to use data binding? His relief makes this way easier.

-one
source

Source: https://habr.com/ru/post/1502038/


All Articles