绑定到可观察的 属性,但显示不可观察的子 属性
Bind to observable property, but show a non-observable sub-property
我正在尝试编写基于 MVVM 和 WinUI3 的应用程序。我有一个 ViewModel 属性、SelectedFolder,它是可观察的(使用 MVVM 工具包)。这是 Folder 类型,它是一个普通的旧 class。像这样:
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 的需要创建另一个具有可观察属性的“文件夹”class。我不想这样做,因为它会重复很多代码。
- 向我的 ViewModel 添加一个可观察字符串 属性:“SelectedFolderName”。
- 滥用转换器并编写一个 GetNamePropertyConverter,这看起来真的很愚蠢。
像这样绑定到模型的 Name
属性 应该有效,因为您正在设置 SelectedFolder
并为其引发 PropertyChanged
事件:
<TextBlock Text="{Binding ViewModel.SelectedFolder.Name} " />
一般来说,您不应直接绑定到包含“业务逻辑”的模型对象。相反,您应该将模型 属性 包装在视图模型中并绑定到包装器属性:
public class ViewModel : ObservableRecipient
{
private Folder selectedFolder;
public FolderModel SelectedFolder
{
get => selectedFolder;
set
{
SetProperty(ref selectedFolder, value, true);
OnPropertyChanged(nameof(FolderName));
}
}
public string FolderName => selectedFolder?.Name;
}
XAML:
<TextBlock Text="{Binding FolderName}" />
我正在尝试编写基于 MVVM 和 WinUI3 的应用程序。我有一个 ViewModel 属性、SelectedFolder,它是可观察的(使用 MVVM 工具包)。这是 Folder 类型,它是一个普通的旧 class。像这样:
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 的需要创建另一个具有可观察属性的“文件夹”class。我不想这样做,因为它会重复很多代码。
- 向我的 ViewModel 添加一个可观察字符串 属性:“SelectedFolderName”。
- 滥用转换器并编写一个 GetNamePropertyConverter,这看起来真的很愚蠢。
像这样绑定到模型的 Name
属性 应该有效,因为您正在设置 SelectedFolder
并为其引发 PropertyChanged
事件:
<TextBlock Text="{Binding ViewModel.SelectedFolder.Name} " />
一般来说,您不应直接绑定到包含“业务逻辑”的模型对象。相反,您应该将模型 属性 包装在视图模型中并绑定到包装器属性:
public class ViewModel : ObservableRecipient
{
private Folder selectedFolder;
public FolderModel SelectedFolder
{
get => selectedFolder;
set
{
SetProperty(ref selectedFolder, value, true);
OnPropertyChanged(nameof(FolderName));
}
}
public string FolderName => selectedFolder?.Name;
}
XAML:
<TextBlock Text="{Binding FolderName}" />