我正在使用MVVM Light Toolkit的V3 SP1开发Silverlight应用程序。
我的申请完全是法语/英语。所有UI元素(按钮,标签等)和所有数据(模型)。我需要动态语言切换,这是完全实现的,适用于来自资源文件的任何内容。我正在努力的是ViewModels。
模型具有特定于语言的属性(DescriptionEn,DescriptionFr)和一个附加属性调用LocalizedDescription,它使用当前区域性来返回调用特定于语言的属性。
当语言发生变化时(通过按钮点击),我举起并广播(通过Messenger)一个属性更改事件。
在我的每个ViewModel中,我注册接收语言交换的属性更改消息。
我想通知ViewModel的所有属性已发生变化。
PropertyChanged事件可以通过使用null或String.Empty作为PropertyChangedEventArgs中的属性名来指示对象上的所有属性都已更改。
但是,由于工具包使用RaisePropertyChanged(...)抽象了已更改事件的引发,因此我无法使其工作。我还检查了takeit的源代码并发现RaisePropertyChanged调用VerifyPropertyName(..)而后者返回错误,该属性不属于ViewModel。我还注意到VerifyPropertyName方法属于Conditional(“DEBUG”),但即使我选择Release配置,仍然会引发ArgumentException(“找不到属性”)。
除了为ViewModel的每个属性手动调用RaisePropertyChanged之外,有没有人知道如何使用工具包使用它?
随访:
基于Simon的评论,我试图创建自己的类来扩展ViewModelBase。我查看了CodePlex上的源代码,并决定创建一个名为RaiseAllPropertyChanged()的方法。它只是RaisePropertyChanged(字符串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()
,该方法使用PropertyChangedEventArgs
实例化String.Empty
类。现在这是我的ViewModels的新子类。
再次感谢西蒙领导的方式!
答案 0 :(得分:2)
不幸的是,目前的MVVMLight代码库
是不可能的短期内你有两个选择
用户自己的自定义基类。自定义基类我的意思是“不要从MVVMLight类继承”
在发布模式下下载并编译MVVMLight。这将强制排除“VerifyPropertyName”方法。当然,你没有得到财产名称检查的价值。
我相信Laurent Bugnion很快就会解决这个问题。
答案 1 :(得分:2)
如果您在2016年阅读此内容,则可以使用ObservableObject并通过执行以下操作通知所有属性已更改:
RaisePropertyChanged(string.Empty);
答案 2 :(得分:1)
解决此问题的一个较轻的解决方案是覆盖类中的RaisePropertyChanged(string 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));
}
}
}