英文:
NotifyPropertyChangedFor not working on ObservableObject
问题
我现在有点迷失。我在一个小应用程序中使用CommunityToolkit.Mvvm来进行MVVM开发。我的用户界面包括一些设置和一些参数;当属性更改时,我正在更新(执行计算)。
在这种情况下,我想要在我对相机的焦距进行计算时触发NotifyPropertyChangedFor
,但从未触发。
所以,虽然使用“本地”属性的事情进展顺利,但通过服务传入的对象(因此是通过依赖注入的对象)如焦距却存在问题。
简化的示例:
我有一个数据容器,如下所示:
public partial class Settings : ObservableObject
{
private CameraSettings cameraSettings;
public CameraSettings CameraSettings
{
get => cameraSettings ?? (cameraSettings = new CameraSettings());
set => SetProperty(ref cameraSettings, value);
}
}
还有一个实际保存值的对象:
public partial class CameraSettings: ObservableObject
{
private int focalLength = 15;
public int FocalLength
{
get => focalLength;
set => SetProperty(ref focalLength, value);
}
}
我有一个视图模型,应该使用它:
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ResultsEditorBox))]
private CameraSettings cameraSettingsContainer;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ResultsEditorBox))]
private string connectionType;
public SettingsViewModel(SettingsService settingsService)
{
cameraSettingsContainer = settingsService.Settings.CameraSettings;
}
ResultEditorBox
只是另一个本地属性,用于更新用户界面:
public string ResultsEditorBox
{
get
{
return "UI update done";
}
}
当使用任何“本地”可观察属性,比如connectionType
时,一切都按预期工作,并且最终调用了ResultsEditorBox
。
如果我对我的自定义对象cameraSettingsContainer
执行相同操作,我可以看到set => SetProperty(ref focalLength, value);
被正确调用;但是NotifyPropertyChangedFor
不会触发。
根据我的理解,通过CommunityToolkit.Mvvm应该可以工作。但是为什么NotifyPropertyChangedFor
在CameraSettings对象上不起作用呢?
英文:
I'm a little lost right now. I'm using the CommunityToolkit.Mvvm for MVVM in a small application.
My UI consists of some settings and some parameters; I'm updating (performing calculations) once a property changes.
In this case I'd like to fire NotifyPropertyChangedFor
as I do calculations with the focal length of a camera - but this gets never triggered.
So while things are working nicely with 'local' properties I'm having issues with objects that come in via a service (so iot injected) like the focal length.
Simplified example:
I have a data container like this:
public partial class Settings : ObservableObject
{
private CameraSettings cameraSettings;
public CameraSettings CameraSettings
{
get => cameraSettings ?? (cameraSettings = new CameraSettings());
set => SetProperty(ref cameraSettings, value);
}
}
And an object that is actually holding the values:
public partial class CameraSettings: ObservableObject
{
private int focalLength = 15;
public int FocalLength
{
get => focalLength;
set => SetProperty(ref focalLength, value);
}
}
And I have a viewmodel which is supposed to use this:
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ResultsEditorBox))]
private CameraSettings cameraSettingsContainer;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ResultsEditorBox))]
private string connectionType;
public SettingsViewModel(SettingsService settingsService)
{
cameraSettingsContainer = settingsService.Settings.CameraSettings;
}
The ResultEditorBox
is just another local property to update UI
public string ResultsEditorBox
{
get
{
return "UI update done";
}
}
While using any 'local' observed property like connectionType
everything is working as expected and ResultsEditorBox
gets called in the end.
If I do the same with my custom object cameraSettingsContainer
I see that set => SetProperty(ref focalLength, value);
gets called correctly; but the NotifyPropertyChangedFor
doesn't trigger.
To my understanding this should work via the CommunityToolkit.Mvvm.
But why is NotifyPropertyChangedFor
not working via the CameraSettings object?
答案1
得分: 1
你在这里尝试的操作以这种方式是不可能的,因为子属性的更改不会自动传播到最高级别。
[NotifyPropertyChangedFor()]
属性仅适用于 CameraSettingsContainer
属性,而不适用于其子属性。你需要其他方法来触发 ResultsEditorBox
的 PropertyChanged
事件。
解决方法之一是订阅 CameraSettingsContainer
的 PropertyChanged
事件,然后在事件处理程序中引发通知:
public SettingsViewModel(SettingsService settingsService)
{
CameraSettingsContainer = settingsService.Settings.CameraSettings;
CameraSettingsContainer.PropertyChanged += (s,e) =>
{
OnPropertyChanged(nameof(ResultsEditorBox));
}
}
我写了一篇关于 MVVM 源代码生成器的博客系列,你可能会感兴趣。它解释了它们是如何工作的以及底层发生了什么。
英文:
What you're trying to do here is not possible like that, because child property changes are not automatically propagated up to the highest level.
The [NotifyPropertyChangedFor()]
attribute only applies to the CameraSettingsContainer
property, but not its child properties. You'll need some other way to raise the PropertyChanged
event for ResultsEditorBox
.
One way to solve this would be to subscribe to the PropertyChanged
event of the CameraSettingsContainer
and then raise the notification in the event handler:
public SettingsViewModel(SettingsService settingsService)
{
CameraSettingsContainer = settingsService.Settings.CameraSettings;
CameraSettingsContainer.PropertyChanged += (s,e) =>
{
OnPropertyChanged(nameof(ResultsEditorBox));
}
}
I wrote a blog series about MVVM Source Generators, which you may be interested in. It explains how they work and what happens under the hood.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论