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&#34 ;; - 加上
textBox1.Text = cl.val;
然后在两个textBoxs刷新值
那是为什么?
答案 0 :(得分:1)
为了在数据源属性被代码更改时使数据绑定工作,数据源(在您的情况下为Class1
)必须提供某种属性更改通知。可能的选择是名为PropertyNameChanged
的事件,其中PropertyName
是应用更改通知的属性的名称,或者更通用的方法是实现INotifyPropertyChanged Interface。
以下是使用第二种方法的示例。由于C#auto属性不能再使用,人们通常会创建一个基类来减少所需的重复样板代码
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); }
}
}
一旦你这样做,一切都会按预期工作。
如果您说您的类是由EF自动生成的,那么您需要创建一个包装类(通常称为ViewModel)以用于UI数据绑定。通常,DTO,实体等类不能直接在UI中使用。
更新虽然上述所有方法都是正确的方法,但为了完整起见,这是一种快速而肮脏的方法。
辅助功能:
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);
}
答案 1 :(得分:0)
试试这个:
cl.val+="11";
textBox1.ResetBindings();
textBox2.ResetBindings();
的更新强>
事实是,当您更改类值时,必须通知UI基础数据已更改,因此您必须在类中实现INotifyPropertyChanged。像这样定义你的类Class1并尝试它:
class Class1:INotifyPropertyChanged
{
private string _val;
public string val
{
get
{
return this._val;
}
set
{
if (this._val != value)
{
this._val = value;
NotifyPropertyChanged("");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
更新2
正如Ivan和我解释的那样,实现它的方法是实现INotifyPropertyChanged。但是如果你想要一种肮脏的方式,你可以清除数据绑定并再次添加它们,例如:
cl.val += "11";
foreach (Control c in this.Controls)
{
if (c is TextBox)
{
c.DataBindings.Clear();
c.DataBindings.Add("Text", cl, "val", false, DataSourceUpdateMode.OnPropertyChanged);
}
}