【问题标题】:Bind to observable property, but show a non-observable sub-property绑定到可观察属性,但显示不可观察的子属性
【发布时间】: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 的数据绑定值,则无需执行任何其他操作。

标签: c# mvvm winui-3


【解决方案1】:

像这样绑定到模型的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}" />

【讨论】:

  • 是的,你完全正确。我创建了一个新项目,它可以工作。我想我可能在 WinUI3 1.0 Preview 中遇到了一些错误。我也遇到过与绑定相关的崩溃 (github.com/microsoft/microsoft-ui-xaml/issues/3680)。当然也有可能我只是在某个地方出现了一个愚蠢的错字......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 2020-06-05
  • 2015-11-30
  • 1970-01-01
相关资源
最近更新 更多