我正在处理正在进行的项目中的代理问题。该类是一个GUI组件,它接受标签和值。这里的想法是用户可以指定标签,然后从任何地方链接一个值(更具体地说,该值的ToString方法),以便每次更新该值时,GUI组件也是如此。这是它如何设置的基础:
public delegate string GUIValue();
public class GUIComponent
{
GUIValue value = null; // The value linked in
string label = ""; // The label for the value
string text = ""; // The label and value appended together
public GUIComponent(string Text, GUIValue Value)
{
this.text = Text;
this.value += Value;
}
public void Update()
{
this.text = this.label + this.value();
}
}
然后我称之为
GUIComponent component = new GUIComponent("Label: ",
new GUIValue(this.attribute.ToString));
代码正确编译,组件显示,并显示给定属性的初始值,但是,只要属性值发生更改,它就不会更新。
我的问题是,我是否首先将此设置正确,如果是这样,为什么它不起作用。我最初的想法是它只接受ToString方法的第一个值返回,因为它不接受任何参数,但任何人都可以验证吗?
答案 0 :(得分:1)
需要调用代理人
你所拥有的是value
引用this.attribute.ToString
方法。
这意味着当您调用this.value()
时,将调用该函数。
当您更改this.attribute
的值时,您可能通过将其引用到包含不同值的其他对象来实现此目的。
所以我猜你所遇到的是,每次拨打update()
时,都会显示旧值。这是因为垃圾收集器不会破坏旧对象,因为您通过委托持有对它的引用。
当您更改属性的值时,GUI委托仍然保留旧对象的方法而不是新对象的方法。
答案 1 :(得分:1)
此代码:
new GUIValue(this.attribute.ToString)
每次属性更改时,都不会导致调用该方法。您必须存储代理并在每次有人更改“属性”时调用它。类似的东西:
private event GUIValue attributeChanged = () => this.attribute.ToString();
private String attribute;
// This is a property that sets the value of attribute
public String Attribute { get { return attribute; } set { attribute = value; attributeChanged(); } }
// Now you can initialize the component using:
// GUIComponent component = new GUIComponent("Label: ", this.attributeChanged);
答案 2 :(得分:1)
你有一半。我认为正在发生的事情是,尽管你最初可以得到这个值,但是你的GuiComponent并没有告诉任何类实际拥有作为GUIValue委托给出的方法,该值实际已经改变并重新获得它。告诉其他对象事件发生的常规方法是一个事件,其他对象通过传入将在事件被引发时运行的委托来“订阅”。
以下是我构建代码的方法:
public interface IHaveAValueYouNeed
{
string ValueGetter();
event EventArgs ValueChanged;
}
public class GUIComponent
{
public delegate string ValueGetter();
ValueGetter getter; // The value linked in
string label = ""; // The label for the value
string text = ""; // The label and value appended together
public GUIComponent(string Text, IHaveAValueYouNeed getter)
{
this.text = Text;
this.getter += getter.ValueGetter;
getter.ValueChanged += ValueUpdatedHandler;
}
public void Update()
{
this.text = this.label + this.value();
}
public void ValueUpdatedHandler(object sender, EventArgs e)
{
Update();
}
}
现在,当您将接口的实现传递给组件时,组件将与实例交换委托,获取对其ValueGetter的引用并订阅其事件。然后IHaveAValueYouNeed的实现应该在值发生变化时(直接或因为会改变getter生成的计算值的某些内容发生变化)引发事件。这样,控制该值的对象可以告诉对该值感兴趣的人,它已经改变了。
答案 3 :(得分:1)
为什么不使用ToString?
public class GUIComponent
{
object value = null; // The value linked in
string label = ""; // The label for the value
string text = ""; // The label and value appended together
public GUIComponent(string Text, object Value)
{
this.text = Text;
this.value = Value;
}
public void Update()
{
this.text = this.label + this.value.ToString();
}
}