You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助INotifyPropertyChanged实现属性间的绑定桥接?

MVVM架构下View与DomainModel解耦的优雅属性桥接方案

背景

我开发了一个采用MVVM架构的应用,其中一组DomainModel类均实现了INotifyPropertyChanged接口,数据会根据内部逻辑自动更新。程序通过绑定ViewModel在View上展示部分数据,我希望将View与DomainModel的实现细节彻底解耦,同时符合迪米特法则。

当前绑定与期望目标

当前绑定代码

<StatusBarItem Visibility="{Binding Status.Connected, Converter={StaticResource BoolToVisibilityConverter}}">
    <TextBlock Text="{Binding SystemTime.Time, StringFormat='HH:mm:ss dd.MM.yyyy'}"/>
</StatusBarItem>

期望的绑定代码

<StatusBarItem Visibility="{Binding Connected, Converter={StaticResource BoolToVisibilityConverter}}">
    <TextBlock Text="{Binding SystemTime, StringFormat='HH:mm:ss dd.MM.yyyy'}"/>
</StatusBarItem>

现有尝试与疑问

我了解CommunityToolkit.Mvvm中有如下特性:

[NotifyPropertyChangedFor(nameof(FullName))]
private string? name;

它会在Name属性变化时自动触发FullName的变更通知,但我需要的是反向逻辑——当DomainModel中的Time属性变化时,通知ViewModel中对应的SystemTime属性更新。

我坚持一个原则:DomainModel绝对不能知晓ViewModel的任何信息,这属于不良架构设计,模型层不应依赖视图相关的内容。

我尝试过手动订阅变更事件的方案:

public class StatusBarViewModel : ObservableObject
{
    private readonly DomainDataService _dataService;
    private readonly ConnectionStatusService _statusService;

    public long Speed => _statusService.Speed;
    public bool Connected => _statusService.Connected;
    public DateTime SystemTime => _dataService.SystemTime.Time;

    public StatusBarViewModel(DomainDataService dataService, ConnectionStatusService statusService)
    {
        _dataService = dataService;
        _statusService = statusService;
        _statusService.PropertyChanged += (_, args) =>
        {
            switch (args.PropertyName)
            {
                case nameof(_statusService.Speed):
                    OnPropertyChanged(nameof(Speed));
                    break;
                case nameof(_statusService.Connected):
                    OnPropertyChanged(nameof(Connected));
                    break;
            }
        };
        _dataService.SystemTime.PropertyChanged += (_, args) =>
        {
            if(args.PropertyName == nameof(_dataService.SystemTime.Time))
                OnPropertyChanged(nameof(SystemTime));
        };
    }
}

但这个方案过于繁琐,当属性数量增多时,代码会变得臃肿,而且我担心大量的事件订阅会影响性能。有没有更优雅的属性桥接方式?

更新1:当前ViewModel实现

public class StatusBarViewModel : ObservableObject
{
    public SystemTime SystemTime { get; }
    public ConnectionStatusService Status { get; }

    public StatusBarViewModel(DomainDataService dataService, ConnectionStatusService statusService)
    {
        SystemTime = dataService.SystemTime;
        Status = statusService;
    }
}

内容的提问来源于stack exchange,提问作者Ж. Сергей

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:20:07