问题描述
class Class1
{
public string val {get;set;}
}
Class1 cl;
private void Form1_Load(object sender, EventArgs e)
{
cl = new Class1();
textBox1.DataBindings.Add("Text",cl,"val",false,DataSourceUpdateMode.OnPropertyChanged,);
textBox2.DataBindings.Add("Text", cl, "val", false, DataSourceUpdateMode.OnPropertyChanged);
}
private void button1_Click(object sender, EventArgs e)
{
cl.val += "11";
}
我更改了 textBox1 中的值,textBox2 中的值也立即更改.
如果我单击按钮,绑定值 cl.val 会从代码中更改,但两个 textBox 值都保持不变.
如果 cl.val 从代码中更改,如何刷新文本框表单上的数据?
PS:如果在行之后
cl.val += "11";- 添加
textBox1.Text = cl.val;
然后在两个文本框处刷新值
这是为什么?
I change value in textBox1, at textBox2 value changes immediatly too.
If I click button, bindings value cl.val changed from code, but both textBox value stay unchanged.
How to refresh data on textbox form if cl.val change from code?
PS: if after row
cl.val += "11"; - add
textBox1.Text = cl.val;
then value refresh at both textBoxs
why is that?
推荐答案
为了在数据源属性被代码更改时使数据绑定工作,数据源(Class1
在您的情况下)必须提供某种属性更改通知.可能的选择是称为 PropertyNameChanged
的事件,其中 PropertyName
是更改通知适用的属性的名称,或者更通用的方法是实现 INotifyPropertyChanged 接口.
In order to make data binding work when data source property is changed by a code, the data source (Class1
in your case) must provide some sort of a property change notification. The possible choices are events called PropertyNameChanged
where PropertyName
is the name of the property for which the change notification applies, or more general approach is to implement INotifyPropertyChanged Interface.
这是使用第二种方法的示例.由于无法再使用 C# 自动属性,人们通常会创建一个基类来减少像这样所需的重复样板代码
Here is an example using the second approach. Since the C# auto properties cannot be used anymore, people usually create a base class to reduce repetitive boilerplate code needed like this
public abstract class BindableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
protected static bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
然后如下使用
class Class1 : BindableObject
{
private string _val;
public string val
{
get { return _val; }
set { SetProperty(ref _val, value); }
}
}
执行此操作后,一切都会按预期进行.
Once you do this, everything will work as expected.
如果如您所说,您的类是由 EF 自动生成的,那么您需要创建一个包装类(通常称为 ViewModel)以用于 UI 数据绑定.通常,DTO、实体等类不能直接在 UI 中使用.
If as you said your class is auto generated by EF, then you need to create a wrapper class (usually referred as ViewModel) to be used for UI data binding. In general, DTOs, Entities etc. classes are not for direct use in the UI.
更新 虽然以上所有方法都是正确的方法,但为了完整起见,这里提供了一种快速而肮脏的方法.
Update While all the above is the right way to go, for the sake of completeness, here is a quick and dirty approach.
辅助函数:
public static class DataBindingUtils
{
public static void RefreshBindings(this BindingContext context, object dataSource)
{
foreach (var binding in context[dataSource].Bindings.Cast<Binding>())
binding.ReadValue();
}
}
示例用法:
private void button1_Click(object sender, EventArgs e)
{
cl.val += "11";
BindingContext.RefreshBindings(cl);
}
这篇关于C# WInForms TextBox DataBinding 刷新 TetxtBox.Text 如果 bindings 属性更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!