mvvm-prismv2-INotifyPropertyChanged
因为这太长了,而且确实没有提出一个连贯的问题:
1:在视图模型中实现主要对象的子属性的正确方法是什么?
2:有没有人找到解决 delegatecommand.RaiseCanExecuteChanged 问题的方法?或者我需要自己修复它,直到 MS 修复为止?
对于故事的其余部分...继续。
在我的视图模型中,我有一个与我的 Model.Doctor 绑定的 doctor 对象属性,它是一个 EF POCO 对象。我在 setter 中有 onPropertyChanged("Doctor") ,如下所示:
Private Property Doctor() As Model.Doctor
Get
Return _objDoctor
End Get
Set(ByVal Value As Model.Doctor)
_objDoctor = Value
OnPropertyChanged("Doctor")
End Set
End Property
如果整个对象发生更改,则唯一一次触发 OnPropertyChanged 。这不会是一个问题,除了我需要知道 doctor 的属性何时发生变化,以便我可以启用表单上的其他控件(例如保存按钮)。我尝试以这种方式实现它:
Public Property FirstName() As String
Get
Return _objDoctor.FirstName
End Get
Set(ByVal Value As String)
_objDoctor.FirstName = Value
OnPropertyChanged("Doctor")
End Set
End Property
这是从 Karl Shifflet 的 XAMLPowerToys 控件中获取的,所以我必须假设它是正确的。但对于我的一生,我无法让它发挥作用。
我在这里包含了 PRISM,因为我使用统一容器来实例化我的视图,并且它是一个单例。我通过 eventaggregator 收到视图模型的更改通知,然后用新值填充 Doctor。我做这一切的原因是因为 PRISM 的 DelegateCommand。所以也许这才是我真正的问题。
DelegateCommand 中似乎存在一个错误,该错误不会在实现该方法的命令上触发 RaiseCanExecuteChanged 方法,因此需要手动触发。我的 onPropertyChangedEventHandler 中有相应的代码。当然,这也不是通过 ICommand 接口实现的,因此我必须中断并创建我的属性 DelegateCommand(of X),以便我可以访问每个命令的 RaiseCanExecuteChanged。
Since this is so long and prolapsed and really doesnt ask a coherent question:
1: what is the proper way to implement subproperties of a primary object in a viewmodel?
2: Has anyone found a way to fix the delegatecommand.RaiseCanExecuteChanged issue? or do I need to fix it myself until MS does?
For the rest of the story...continue on.
In my viewmodel i have a doctor object property that is tied to my Model.Doctor, which is an EF POCO object. I have onPropertyChanged("Doctor") in the setter as such:
Private Property Doctor() As Model.Doctor
Get
Return _objDoctor
End Get
Set(ByVal Value As Model.Doctor)
_objDoctor = Value
OnPropertyChanged("Doctor")
End Set
End Property
The only time OnPropertyChanged fires if the WHOLE object changes. This wouldnt be a problem except that I need to know when the properties of doctor changes, so that I can enable other controls on my form(save button for example). I have tried to implement it in this way:
Public Property FirstName() As String
Get
Return _objDoctor.FirstName
End Get
Set(ByVal Value As String)
_objDoctor.FirstName = Value
OnPropertyChanged("Doctor")
End Set
End Property
this is taken from the XAMLPowerToys controls from Karl Shifflet, so i have to assume that its correct. But for the life of me I cant get it to work.
I have included PRISM in here because I am using a unity container to instantiate my view and it IS a singleton. I am getting change notification to the viewmodel via eventaggregator that then populates Doctor with the new value. The reason I am doing all this is because of PRISM's DelegateCommand. So maybe that is my real issue.
It appears that there is a bug in DelegateCommand that does not fire the RaiseCanExecuteChanged method on the commands that implement it and therefore needs to be fired manually. I have the code for that in my onPropertyChangedEventHandler. Of course this isnt implemented through the ICommand interface either so I have to break and make my properties DelegateCommand(of X) so that I have access to RaiseCanExecuteChanged of each command.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 Josh Smith 的 RelayCommand 而不是 DelegateCommand。它修复了 CanExecute 命令未引发的问题,并且不会像 DelegateCommand 那样泄漏内存:
“它将事件订阅委托给 CommandManager.RequerySuggested 事件。这可确保 WPF 命令基础结构询问所有 RelayCommand 对象是否每当它询问内置命令时就可以执行。”
Use Josh Smith's RelayCommand instead of the DelegateCommand. It fixes the issue with CanExecute commands not being raised, and doesn't leak memory like the DelegateCommand:
"It delegates the event subscription to the CommandManager.RequerySuggested event. This ensures that the WPF commanding infrastructure asks all RelayCommand objects if they can execute whenever it asks the built-in commands."
关于 2:Microsoft 没有需要修复的错误,因为按照设计,您必须明确告诉命令重新评估自身。当然,您可以不同意他们的决定。
如果您希望在 RaiseCanExecuteChanged 触发时重新评估 DelegateCommands,请参阅 http: //compositewpf.codeplex.com/Thread/View.aspx?ThreadId=47338
About 2: There is no bug to fix by Microsoft, since it is by design that you have to explicitely tell the command to re-evaluate itself. Of course you may disagree with their decision.
If you want to have the DelegateCommands re-evaluate whenever RaiseCanExecuteChanged is fired, see http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=47338