【发布时间】:2021-11-22 12:58:05
【问题描述】:
我正在尝试编写一个基于 MVVM 和 WinUI3 的应用程序。我有一个 ViewModel 属性 SelectedFolder,它是可观察的(使用 MVVM Toolkit)。这是文件夹类型,它是一个普通的旧类。像这样的:
public class ViewModel: ObservableRecipient {
private Folder selectedFolder;
public FolderModel SelectedFolder
{
get => selectedFolder;
set => SetProperty(ref selectedFolder, value, true);
}
}
public class FolderModel {
public string Name { get; set; }
}
现在在我的 XAML 中,我想绑定 ViewModel.SelectedFolder,并对它的更改做出反应,但我想显示 ViewModel.SelectedFolder.Name。所以我正在寻找这样的东西(不存在):
<TextBlock Text="{Binding ViewModel.SelectedFolder,Property=Name" />
我怎样才能做到这一点?我想到的事情:
- 让一切都可以观察到。这行得通,但我试图避免这种情况,以便分离我的模型和我的视图模型。原因是我的真实模型比这个例子复杂得多,我试图让它接近对我的“业务逻辑”有意义的东西,并使我的视图模型满足我的视图需求。
- 为我的 ViewModel 的需要创建另一个具有可观察属性的“文件夹”类。我不想这样做,因为它会重复很多代码。
- 向我的 ViewModel 添加一个可观察的字符串属性:“SelectedFolderName”。
- 滥用转换器,写一个GetNamePropertyConverter,看起来真的很傻。
【问题讨论】:
-
让一个模型可观察,你希望它的变化是可观察的,这似乎是这里最直接的设计选择。您不需要让每个属性都可观察。
-
是的,但是文件夹的属性不会改变,它基本上是不可变的。我想换掉整个对象。
-
因为您的 ViewModel 是可观察的,所以当
SelectedFolder更改时,如果您将其绑定为{Binding ViewModel.SelectedFolder.Name},则新的Name属性值将显示在 UI 中。如果您只想在SelectedFolder设置为新值时更改Name的数据绑定值,则无需执行任何其他操作。