当父级变为 null 时,uwp 绑定到子级 属性 不会更新

uwp binding to child property doesn't update when parent becomes null

我有一个对象 ItemDescription 的嵌套绑定,默认情况下 MyEvidence 属性 为空,因此它显示空白,但只要我将其值设置为 EvidenceDTO 对象,itemDescription 值就会按预期显示。

现在,当我再次将 MyEvidence 属性 设置为 null 时,我希望 ItemDescription 文本再次为空,但这并没有发生,显然它不知道父对象现在是 changed/nulled 所以子对象不应该再出现了。我在 ViewModel class 上设置了 INotifyPropertyChanged,因此在 MyEvidence 属性 以及 EvidenceDTO 中的 ItemDescription 属性 上设置了一个助手 class作为 可观察

Xaml绑定

<TextBlock Text="{x:Bind ViewModel.MyEvidence.ItemDescription, Mode=OneWay}" />

像这样在页面后端初始化ViewModel

public MainViewModel ViewModel { get; } = new MainViewModel();

我的视图模型代码

public class MainViewModel : Observable
{
    private EvidenceDTO _myEvidence;
    public EvidenceDTO MyEvidence { get => _myEvidence; set => Set(ref _myEvidence, value); }
}

EvidenceDTO

public class EvidenceDTO : Observable
{
    private string _itemDescription;
    public string ItemDescription { get => _itemDescription; set => Set(ref _itemDescription, value); }
}

可观察到Class

public class Observable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return;
        }

        storage = value;
        OnPropertyChanged(propertyName);
    }

    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

我以 ItemDescription 为例,EvidenceDTO 的更多属性以类似的方式显示在 UI 上,因此我需要一些通用解决方案,其中 属性 更改通知在绑定路径的所有级别上都被提升。

好像当你设置MyEvidence为null时,它仍然会显示之前缓存的值,当重新初始化MyEvidence时,它会根据属性值重新显示。所以如果你想再次显示 ItemDescription 文本为空白,最好重新初始化 MyEvidence,如:

private void Button_Click(object sender, RoutedEventArgs e)
{
    ViewModel.MyEvidence = new EvidenceDTO();
}

如果你有不止一层的嵌套模型,你可以在嵌套模型的每一层中像下面这样设置模型。当你设置MyEvidence为null时,会触发MyEvidence的get方法,然后在get方法中重新初始化。

public EvidenceDTO MyEvidence
{
    get
    {
        if (_myEvidence == null)
        {
            _myEvidence = new EvidenceDTO();
        }
        return _myEvidence;
    }
    set => Set(ref _myEvidence, value);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    ViewModel.MyEvidence = null;
}

设置你的属性ViewModel.MyEvidence=null,不释放你的MyEvidence对象。对象的引用超出范围,你应该尝试给你的 ViewModel.MyEvidence 一个新的引用。试试下面一个=> ViewModel.MyEvidence = 新的 EvidenceDTO();