2016-06-09 50 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,将自动更新视图。