2011-02-04 28 views
3

我在一個正在處理的項目的類中有一個委託出現問題。該類是一個同時接受標籤和值的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

你什麼時候調用`Update`方法? – Justin 2011-02-04 18:36:50

+0

每幀更新方法由遊戲代碼自動調用。 – shmeeps 2011-02-04 18:38:13

回答

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); 
1

委託需要被調用。
你在那裏有value參考this.attribute.ToString方法。

這意味着當你打電話給this.value()時,那個函數將被調用。

當您更改this.attribute的值時,您可能是通過將其引用到包含不同值的其他對象來實現的。
所以我想你正在經歷的是每次你撥打update()那麼舊值就會出現。這是因爲舊對象不會被垃圾收集器銷燬,因爲您通過委託持有對它的引用。

當您更改屬性的值時,GUI委託仍然保存舊對象的方法,而不是新的。

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的計算值而改變的東西)。這樣,控制價值的對象可以告訴人們對它已經改變的價值感興趣。

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(); 
    } 
}