gpt4 book ai didi

c# - .NET WinForms INotifyPropertyChanged 在更改时更新所有绑定(bind)。更好的方法?

转载 作者:IT王子 更新时间:2023-10-29 04:27:51 25 4
gpt4 key购买 nike

在 Windows 窗体应用程序中,触发 INotifyPropertyChanged 的​​属性更改将导致窗体从我的绑定(bind)对象读取每个属性,而不仅仅是更改的属性。 (参见下面的示例代码)

这似乎是荒谬的浪费,因为接口(interface)需要更改属性的名称。它导致我的应用程序出现大量时钟,因为某些属性 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));
}
}
}

最佳答案

在触发事件时读取所有属性的原因在于触发 ProperyChanged 事件时在绑定(bind)对象上调用的 PushData 方法。如果查看堆栈跟踪,您会注意到调用了内部对象 BindToObject 的 PropValueChanged 方法,该方法又调用了 BindingManager 上的 Oncurrentchanged 事件。绑定(bind)机制会跟踪当前项的更改,但不会进行更细粒度的区分。 “罪魁祸首” PushData 方法调用您的属性上的 getter(查看使用反射器的代码)。所以没有办法解决它。也就是说,根据经验,不建议在 get 和 set 访问器中进行繁重的处理,为此使用单独的 get 和 set 方法(如果可能)

另请查看这篇文章,尤其是这条评论(http://www.codeproject.com/Messages/2514032/How-Binding-watches-control-properties-i-e-how-doe.aspx),它准确解释了 propertychanged 事件是如何触发的,尽管它不会解决您的 getter 问题:http://www.codeproject.com/KB/database/databinding_tutorial.aspx?msg=2514032

探索的一个想法是延迟 getter 被调用。您可以通过使用绑定(bind)的 ControlUpdateMode 属性来实现这一点。当这个值设置为 Never 时,相应的控件在有变化时不会更新。但是,当您将该值切换回 OnPropertyChanged 时,将调用 PushData 方法,因此将访问 getter。因此,考虑到您的示例,此代码将暂时阻止文本框 2 更新:

void but_Click(object sender, EventArgs e)
{
txt2.DataBindings[0].ControlUpdateMode = ControlUpdateMode.Never;
_presenter.SomeText1 = "some text 1";
}

关于c# - .NET WinForms INotifyPropertyChanged 在更改时更新所有绑定(bind)。更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2820447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com