2016-06-09 49 views
0

我有這樣當我的設置也改變時如何改變MVVM屬性?

Public class AboutPageViewModel 
{ 
    public AboutPageViewModel() 
    { 
    AppName = Settings.MyAppName; 
    } 

    private string _appName; 
    public string AppName 
    { 
    get{return _appName;} 
    set{_appName = value; RaisePropertyChanged("AppName");} 
    } 
} 

一個視圖模型現在,在一個靜態類

public static class Settings 
{ 
    public static string MyAppName{get;set;} = "LOL" 
} 

如何通知視圖模型每次MyAppName改變,並且將其更新到綁定的UI?

謝謝!

回答

4

當你在你的問題中定義它,Settings不是一個靜態類(啊,我看到在評論中是一個錯字,而且它是靜態的在你的代碼中)。它不應該是靜態的。 PropertyChanged靜態類上的通知在理論上是可行的,但這不值得你花時間去處理,而且沒有必要打擾。

Settings實現INotifyPropertyChanged,就像你的viewmodel。當MyAppName發生變化時,Settings應該提高PropertyChanged,就像AboutPageViewModel確實在自己的AppName屬性發生變化時一樣。

現在給Settings靜態屬性稱爲Instance

public static Settings Instance { get; private set; } 

static Settings() 
{ 
    Instance = new Settings(); 
} 

而且在AboutPageViewModel處理其PropertyChanged事件:

public AboutPageViewModel() 
{ 
    AppName = Settings.Instance.MyAppName; 
    Settings.Instance.PropertyChanged += (s,e) => 
    { 
     // If you're in C#6: 
     //if (e.PropertyName == nameof(Settings.MyAppName)) 
     if (e.PropertyName == "MyAppName") 
     { 
      AppName = Settings.Instance.MyAppName; 
     } 
    } 
} 

選項二號

可以說是一個更好的選擇;我這樣做了不止一次。

在評論中,@MikeEason說得很好,這也可以通過自定義*Changed事件來完成,比如MyAppNameChanged,它有兩個優點:它可以讓你回到靜態類,它可以讓你跳過檢查屬性名稱,這是額外的代碼,也是"magic string"。與INotifyPropertyChanged一起工作,我們對魔術串的危險有點麻木,但實際上它們很糟糕。如果您使用C#6,那麼您可以絕對應該使用nameof()運算符,但是我們並不是所有人都在使用C#6。我在工作中的主要責任是一個應用程序,我們希望今年夏天遷移到C#6。

public static event EventHandler<String> MyAppNameChanged; 

private static String _myAppName = ""; 
public static String MyAppName { 
    get { return _myAppName; } 
    set { 
     if (_myAppName != value) 
     { 
      _myAppName = value; 
      // C#6 again. Note (thanks OP!) you can't pass this for sender 
      // in a static property. 
      MyAppNameChanged?.Invoke(null, value); 
     } 
    } 
} 

這樣做的缺點是,嗯,這個類叫做Settings,不Setting。也許它有十幾個屬性在不斷變化。這將成爲一個由不同的財產變化事件組成的真正的叢林(你可能會問 - 「那是什麼?」 - 你可能會有一個觀點)。我傾向於堅持使用PropertyChanged,如果其中有一整套,並且如果課程只有一兩個重要的特性需要人們關注,那就添加一個事件。無論哪種方式在我看來令人討厭;嘗試兩種,你最終會選擇一個偏好。

+0

也許'MyAppNameChanged'專用**事件**可能是一個更好的主意?這將允許您防止檢查PropertyChanged上的屬性名稱。 –

+0

感謝您的回答。設置是一個靜態類。我忘了添加這個。 –

+0

^一個事件也可以在靜態類上工作。 –

0

您必須在Settings類上實現INotifyPropertyChanged接口!

然後用同一段代碼是這樣的:

private string _myAppName; 
    public string MyAppName 
    { 
    get{return _myAppName;} 
    set{_appName = value; RaisePropertyChanged("MyAppName");} 
    } 
+0

謝謝。我已經實現了界面 –

2

你不需要在視圖模型值,如果你已經有它的地方(我假設你是不會改變什麼在視圖模型本身):

public class AboutPageViewModel : INotifyPropertyChanged 
{ 
    public string AppName => Settings.MyAppName; 
} 

至於當此屬性更改視圖知道你需要兩件事情:1)當值變爲2應該有一種方式來通知視圖模型)上升PropertyChanged(nameof(AppName))(公告INotifyPropertyChanged)。

幾種可能性,使其:

  1. Settings應該上升的事件時MyAppName值改變,視圖模型訂閱它,並上升PropertyChanged;
  2. 存儲初始值,定期檢查值是否改變;
  3. 使用另一種實現INotifyPropertyChanged的類型,而不是綁定到該類型屬性,如果該類型上升PropertyChanged,將自動更新視圖。