2011-05-20 66 views
6

我正在使用MVVM Light Toolkit的V3 SP1处理Silverlight应用程序。通知所有属性在ViewModel上已更改

我的申请完全是法文/英文。所有UI元素(按钮,标签等)和所有数据(模型)。我需要动态语言切换,这是完全实现的,并且可以处理来自资源文件的任何内容。我所苦恼的是ViewModels。

模型具有特定语言的性质鉴别仪表(DescriptionEn,DescriptionFr),并且使用当前区域性返回调用语言特定属性的附加属性调用LocalizedDescription。

当语言的变化(通过点击一个按钮),我提出和广播(通过信使)一个属性更改事件。

在每一个我的ViewModels的,我注册接收属性更改消息的语言交换。

我想通知ViewModel的所有属性都发生了变化。

来源:http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx

The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs.

然而,由于该工具包的抽象变更活动的募集符合RaisePropertyChanged(...)我不能得到这个工作。我还检查了takeit的来源,并发现RaisePropertyChanged调用VerifyPropertyName(..),然后返回一个错误,该属性不属于ViewModel。我还注意到VerifyPropertyName方法是由Conditional(“DEBUG”)引起的,但即使我选择Release配置,仍会引发ArgumentException(“Property not found”)。

有谁知道的一种方式来获得这种使用工具箱除了手动调用RaisePropertyChanged的视图模型的每个属性的工作?

后续:

基于从西蒙的评论,我试图创建自己的类,它扩展ViewModelBase。我查看了CodePlex的源代码并决定创建一个名为RaiseAllPropertyChanged()的方法。它只是RaisePropertyChanged(string propertyName)的副本,但没有参数,也没有对VerifyPropertyName(...)的调用。我无法让它工作。这是我的。

public class ViewModelBaseExtended : ViewModelBase 
{ 
    protected void RaiseAllPropertyChanged() 
    { 
     var handler = this.PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(String.Empty)); 
     } 
    } 
} 

但我得到一个编译器错误:The event 'GalaSoft.MvvmLight.ViewModelBase.PropertyChanged' can only appear on the left hand side of += or -=。这是在ViewModelBase中使用的代码的副本。

有人可以提供一些建议,如何让这个工作?

解决方案:

我复制从ViewModelBase所有的代码放到一个新的类。然后我添加了上面提到的方法RaisePropertyChanged(),它用String.Empty实例化PropertyChangedEventArgs类。这是我ViewModels的新子类。

再次感谢西蒙领先的方式!

+0

你为什么要通知所有呢? – Simon 2011-05-26 23:00:19

+0

我正在通知所有属性,因为我需要它们重新读取其数据,因为语言发生了变化。例如,我有一个ViewModel有10个属性。这些属性是具有法文和英文描述并在运行时以当前语言呈现的数据的集合。当前语言发生变化时,我需要通知所有属性,以便他们的数据现在以新的当前语言呈现。尽管在实施上述解决方案时,我仍然在努力获取数据来切换语言。但通知所有人的问题已经解决。 – 2011-05-27 17:53:17

回答

2

不幸的是,这是不可能的MVVMLight

当前代码库在短期内你有2个选择

  1. 用户自定义的基类。定制基类我的意思是“不从MVVMLight类继承”

  2. 在发布模式下下载并编译MVVMLight。这将强制排除“VerifyPropertyName”方法。当然,你不会得到属性名称检查的价值。

我相信Laurent Bugnion很快就会解决这个问题。

+0

我已经添加了一个跟踪我的原始问题,并提出了一个新基类的建议。有什么建议么? – 2011-05-24 17:35:53

+0

@Vincenzo更新我的答案。你不能以这种方式访问​​基类中的事件。您需要从头开始创建您自己的自定义基类。 – Simon 2011-05-24 22:27:55

+0

@Vincenzo你在Twitter吗?如果是这样,请通过http://twitter.com/SimonCropp ping我,我们可以讨论这个 – Simon 2011-05-24 22:31:40

1

较轻解决这个问题会一直在你的类重写RaisePropertyChanged(字符串参数propertyName):

protected override void RaisePropertyChanged(string propertyName) 
    { 
     if (propertyName != null) 
     { 
      base.RaisePropertyChanged(propertyName); 
     } 
     else 
     { 
      var handler = PropertyChangedHandler; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(null)); 
      } 

     } 
    } 
2

如果你在2016年读这篇文章,你可以使用ObservableObject,并通知所有的属性已经改变了:

RaisePropertyChanged(string.Empty); 
相关问题