Dav*_*ing 24 .net c# data-binding inotifypropertychanged winforms
在Windows窗体应用程序中,触发INotifyPropertyChanged的属性更改将导致窗体从绑定对象读取每个属性,而不仅仅是属性已更改.(参见下面的示例代码)
这似乎是荒谬的浪费,因为界面需要更改属性的名称.它在我的应用程序中导致大量计时,因为某些属性getter需要执行计算.
如果没有更好的方法,我可能需要在我的getter中实现某种逻辑来丢弃不必要的读取.
我错过了什么吗?有没有更好的办法?不要说使用不同的演示技术 - 我在Windows Mobile上这样做(虽然行为也发生在完整的框架上).
这里有一些玩具代码来演示这个问题.单击该按钮将导致即使一个属性已更改,也会填充两个文本框.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Example
{
public class ExView : Form
{
private Presenter _presenter = new Presenter();
public ExView()
{
this.MinimizeBox = false;
TextBox txt1 = new TextBox();
txt1.Parent = this;
txt1.Location = new Point(1, 1);
txt1.Width = this.ClientSize.Width - 10;
txt1.DataBindings.Add("Text", _presenter, "SomeText1");
TextBox txt2 = new TextBox();
txt2.Parent = this;
txt2.Location = new Point(1, 40);
txt2.Width = this.ClientSize.Width - 10;
txt2.DataBindings.Add("Text", _presenter, "SomeText2");
Button but = new Button();
but.Parent = this;
but.Location = new Point(1, 80);
but.Click +=new EventHandler(but_Click);
}
void but_Click(object sender, EventArgs e)
{
_presenter.SomeText1 = "some text 1";
}
}
public class Presenter : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _SomeText1 = string.Empty;
public string SomeText1
{
get
{
return _SomeText1;
}
set
{
_SomeText1 = value;
_SomeText2 = value; // <-- To demonstrate that both properties are read
OnPropertyChanged("SomeText1");
}
}
private string _SomeText2 = string.Empty;
public string SomeText2
{
get
{
return _SomeText2;
}
set
{
_SomeText2 = value;
OnPropertyChanged("SomeText2");
}
}
private void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(PropertyName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
anc*_*dra 15
触发事件时读取所有属性的原因在于触发ProperyChanged事件时在绑定对象上调用的PushData方法.如果查看堆栈跟踪,您会注意到内部对象BindToObject的PropValueChanged方法被调用,而该方法又调用BindingManager上的Oncurrentchanged事件.绑定机制会跟踪当前项目的更改,但不会进行更细微的区分."罪魁祸首"PushData方法调用属性上的getter(使用反射器查看代码).所以没有办法绕过它.话虽如此,根据经验,在get和set访问器中,不建议进行繁重的处理,为此使用单独的get和set方法(如果可能)
另外看看这篇文章,特别是这篇评论(http://www.codeproject.com/Messages/2514032/How-Binding-watches-control-properties-ie-how-doe.aspx),这完全可以解释如何解决propertychanged事件,虽然它不会解决你的getter问题:http://www.codeproject.com/KB/database/databinding_tutorial.aspx? msg = 2514032
探索的想法是延迟被调用的吸气剂.您可以通过使用绑定的ControlUpdateMode属性来实现此目的.当此值设置为"从不"时,相应的控件将在更改时不会更新.但是,当您将值切换回OnPropertyChanged时,将调用PushData方法,因此将访问getter.因此,考虑到您的示例,此代码将暂时阻止文本框2更新:
void but_Click(object sender, EventArgs e)
{
txt2.DataBindings[0].ControlUpdateMode = ControlUpdateMode.Never;
_presenter.SomeText1 = "some text 1";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18453 次 |
| 最近记录: |