2014-02-20 144 views
1

我想在我的XAML文本字段被綁定到一個屬性PlayerData.Instance.data.MyXP類的結構是這樣的數據綁定到一個單獨的屬性的屬性

class PlayerData 
{ 
    public static PlayerData Instance = new PlayerData(); 

    public UserData data {get;set;} 
} 

class UserData 
{ 
    public int MyXP {get;set;} 
} 

有人能解釋如何(如果有的話)我可以做這個。我已經嘗試了多種從SO上的問題的方法,沒有發現任何成功的方法。我遇到的最大問題是PlayerData.Instance.data是在UI創建後分配的,所以我需要在UserData上使用某種通知事件,也可能在MyXP上,因爲我希望UI在xp更改時更新。

回答

4

通常,當您使用單例時,每個使用它的對象都會獲得Instance屬性的副本。你可以在你的視圖模型對象上創建一個屬性來保存該引用,然後綁定到該屬性。例如:

​​

然後,在你的XAML,假設你已經綁定的Window對象的DataContext屬性視圖模型對象已經,你會使用這樣的:

<TextBlock Text="{Binding Path=PlayerData.data.MyXP}" /> 

您可能還需要指定一個實現IValueConverter接口的對象來正確地格式化int MyXP屬性。 (請注意,如圖所示,如果您有多線程環境,那麼您的代碼不是單例模式的有效實現。請參閱this article,並查看部分標題「在C#中實現Singleton模式的第四種方式:多線程單例模式「,如果你的代碼是多線程的)。

+0

+1,只是在OP不使用MVVM的情況下添加解決方案。 – Romasz

+0

工程很好。感謝您的建議! –

1

您需要實現INotifyPropertyChanged並設置TextBlockDataContext到您的實例:

class PlayerData 
{ 
    public static PlayerData Instance = new PlayerData(); 

    private UserData data = new UserData(); 
    public UserData Data 
    { 
     get { return data; } 
     set { data = value; } 
    } 
} 

class UserData : INotifyPropertyChanged 
{ 
    private int myXP = 0; 
    public int MyXP 
    { 
     get { return myXP; } 
     set 
     { 
      myXP = value; 
      RaiseProperty("MyXP"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void RaiseProperty(string property = null) 
    { 
     if (this.PropertyChanged != null) 
      this.PropertyChanged(this, new PropertyChangedEventArgs(property)); 
    } 
} 

在XAML中,你可以做這樣的:

<TextBlock Name="myExp" Text="{Binding Data.MyXP}" Grid.Row="2"/> 

,並使其工作,你需要將TextBlockDataContext設置爲您的實例:

myExp.DataContext = PlayerData.Instance; 

然後,您可以自由chenge你的XP,你應該看到它,它的用戶界面:

PlayerData.Instance.Data.MyXP = 1000; 

您也可以讓你的PlayerData : INotifyPropertyChanged如果你有其他地方的數據綁定。希望這個例子會告訴你它是如何工作的。