2015-01-05 38 views
1

在我解釋問題之前,在一個句子中總結我的曲折問題。我怎樣才能使它,如果我更新從我的詞典中的鍵的值,它會觸發與該鍵/ TextBinding關聯的OnPropertyChanged方法,或者我應該這樣做一個不同的方式數據綁定像Unity一樣的行爲

我有一些經驗WPF/MVVM數據綁定,所以夢想解決方案適用於我的項目:如果我的遊戲中的值發生更改,它會自動更新當前顯示在UI上的任何位置。

我有一個非常簡陋的地方開始使用字典查找表,但可能會有一些人誰知道我需要什麼,這將更好地工作

的一個代碼塊是BindingBehavior,可以是視爲附加到用戶界面文本字段(相同的父遊戲對象的一個​​組成部分要更精確一點)

如果我將TextBinding設置爲一個值,我的UI更改以反映它,但如果通過我更改了一個值字典似乎是我的字典當時只保存了分配給它的值的副本,並且不更新引用「TextBinding」

編輯:我失去了文本塊不知何故,修補

using UnityEngine; 
using System.Collections; 
using UnityEngine.UI; 
using System; 

public class BindingBehavior : MonoBehaviour 
{ 
    public string BindingName; 
    public string TextInitialValue; 

    private string _textBinding; 
    public string TextBinding 
    { 
     get 
     { 
      return _textBinding; 
     } 
     set 
     { 
      _textBinding = value; 
      NotifyPropertyChanged(value); 
     } 
    } 

    void NotifyPropertyChanged (string value) 
    { 
     this.gameObject.GetComponent<Text>().text = value; 
    } 

    // Use this for initialization 
    void Start() 
    { 
     TextBinding = TextInitialValue; 
     UIManager.Instance.BindingLookUp.Add(BindingName, TextBinding); 
     Debug.Log (BindingName + ", " + TextBinding + " was added to Binding Lookup Dictionary"); 
    } 
} 

以下是可讀性單獨的類

using UnityEngine; 
using UnityEngine.UI; 
using System.Collections; 
using System; 
using System.Collections.Generic; 

public class UIManager 
{ 
    private static UIManager _instance; 
    public static UIManager Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new UIManager(); 
      } 
      return _instance; 
     } 
     set 
     { 
      _instance = value; 
     } 
    } 

    public Dictionary<string, string> BindingLookUp = new Dictionary<string, string>(); 
} 

編輯:使用一個類從一些建議閱讀第二次嘗試堆棧溢出(引用類型?)的其他地方似乎仍然沒有做這項工作。

public class BindableString 
{ 
    private string _stringValue; 
    public string StringValue 
    { 
     get 
     { 
      return _stringValue; 
     } 
     set 
     { 
      _stringValue = value; 
     } 
    } 

    public BindableString(string s) 
    { 
     StringValue = s; 
    } 
} 

public class BindingBehavior : MonoBehaviour 
{ 
    public string BindingName; 
    public string TextInitialValue; 

    private BindableString _textBinding; 
    public BindableString TextBinding 
    { 
     get 
     { 
      return _textBinding; 
     } 
     set 
     { 
      _textBinding = value; 
      NotifyPropertyChanged(value); 
     } 
    } 

    void NotifyPropertyChanged (BindableString str) 
    { 
     this.gameObject.GetComponent<Text>().text = str.StringValue; 
    } 

    // Use this for initialization 
    void Start() 
    { 
     TextBinding = new BindableString(TextInitialValue); 
     UIManager.Instance.BindingLookUp.Add(BindingName, TextBinding); 
     Debug.Log (BindingName + ", " + TextBinding + " was added to Binding Lookup Dictionary"); 
    } 
} 

public class UIManager 
{ 
    private static UIManager _instance; 
    public static UIManager Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new UIManager(); 
      } 
      return _instance; 
     } 
     set 
     { 
      _instance = value; 
     } 
    } 

    public Dictionary<string, BindableString> BindingLookUp = new Dictionary<string, BindableString>(); 
} 

這是我提出來更新文本

UIManager.Instance.BindingLookUp["ActiveCharacterActionPointsRemaining"] = new BindableString(_activeCharacter.actionPointsRemaining.ToString()); 

回答

0

我認爲我有一個解決方案,我很高興在一分鐘文本結合,雖然我將採取它對團結與合作問答網站,看看是否有一種方法做一個更廣義的字典使用gameobjects或組件或東西,這將是一個更穩定的解決方案。這是代碼。事後看來,這似乎很明顯,我不知道爲什麼我先試了一下。

using UnityEngine; 
using System.Collections; 
using UnityEngine.UI; 
using System; 

using UnityEngine; 
using System.Collections; 
using UnityEngine.UI; 
using System; 

public class BindingBehavior : MonoBehaviour 
{ 
    public string BindingName; 
    public string TextInitialValue; 

    public Text TextComponent; 

    public string TextValue 
    { 
     get 
     { 
      if (TextComponent == null) 
      { 
       TextComponent = this.gameObject.GetComponent<Text>(); 
      } 
      return TextComponent.text; 
     } 
     set 
     { 
      if (TextComponent == null) 
      { 
       TextComponent = this.gameObject.GetComponent<Text>(); 
      } 
      TextComponent.text = value; 
     } 
    } 

    // Use this for initialization 
    void Start() 
    { 
     TextValue = TextInitialValue; 
     UIManager.Instance.UITextBindings.Add(BindingName, TextComponent); 
    } 
} 

using UnityEngine; 
using UnityEngine.UI; 
using System.Collections; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 

public class UIManager 
{ 
    private static UIManager _instance; 
    public static UIManager Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new UIManager(); 
      } 
      return _instance; 
     } 
     set 
     { 
      _instance = value; 
     } 
    } 

    public Dictionary<string, Text> UITextBindings = new Dictionary<string, Text>(); 
} 

,並更新我需要簡單地撥打電話

UIManager.Instance.UITextBindings["ActiveCharacterActionPointsRemaining"].text = _activeCharacter.actionPointsRemaining.ToString(); 
0

通話,我認爲最好的辦法是實現自己的ObservableDictionary類觸發該PropertyChanged事件與PropertyName設置爲"Item[]"

這裏有一個示例實現:http://blogs.microsoft.co.il/shimmy/2010/12/26/observabledictionarylttkey-tvaluegt-c/。關鍵的部分是:

private const string CountString = "Count"; 
private const string IndexerName = "Item[]"; 
private const string KeysName = "Keys"; 
private const string ValuesName = "Values"; 

private void Insert(TKey key, TValue value, bool add) 
{ 
    if (key == null) 
     throw new ArgumentNullException("key"); 

    TValue item; 
    if (Dictionary.TryGetValue(key, out item)) 
    { 
     if (add) 
      throw new ArgumentException("An item with the same key has already been added."); 
     if (Equals(item, value)) 
      return; 
     Dictionary[key] = value; 

     OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item)); 
    } 
    else 
    { 
     Dictionary[key] = value; 
     OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value)); 
    } 
} 

private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem) 
{ 
    OnPropertyChanged(); 
    if (CollectionChanged != null) 
     CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem)); 
} 

private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem) 
{ 
    OnPropertyChanged(); 
    if (CollectionChanged != null) 
     CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem)); 
} 

private void OnPropertyChanged() 
{ 
    OnPropertyChanged(CountString); 
    OnPropertyChanged(IndexerName); 
    OnPropertyChanged(KeysName); 
    OnPropertyChanged(ValuesName); 
} 

protected virtual void OnPropertyChanged(string propertyName) 
{ 
    if (PropertyChanged != null) 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
} 
+0

感謝我給這一個嘗試 – Oliver

+0

我得到一個問題,下面一行的UI文本/ T/T/T/t公共類ObservableDictionary :IDictionary ,INotifyCollectionChanged,INotifyPropertyChanged/t/t/t/t它看起來像我在使用系統。ComponentModel它沒有帶來INotifyCollection改變,沒有選項來解決它,它是什麼,我需要做的就是它找到INotifyCollectionChanged – Oliver

+0

您需要引用'System.ObjectModel'組裝。 http://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(System.Collections.Specialized.INotifyCollectionChanged);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k (DevLang-CSHARP)RD =真 –