【问题标题】:uwp binding to child property doesn't update when parent becomes null当父级变为空时,uwp 绑定到子属性不会更新
【发布时间】:2020-02-07 21:45:37
【问题描述】:

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

现在,当我再次将 MyEvidence 属性设置为 null 时,我希望 ItemDescription 文本再次为空白,但这不会发生,显然它不知道父对象现在已更改/为 null,因此子对象不应该不再出现。我在 ViewModel 类上设置了 INotifyPropertyChanged,因此在 MyEvidence 属性以及 EvidenceDTO 中的 ItemDescription 属性上设置了一个名为 Observable

的帮助器类

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); }
}

证据DTO

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

可观察类

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 上,因此我需要一些通用解决方案,其中在绑定路径的所有级别上都会引发属性更改通知。

【问题讨论】:

  • 当您使用编译绑定时,您应该能够调试问题,您这样做了吗?
  • 从来没有真正尝试过调试绑定,不知道这是一个选项,你能给我一个教程吗?
  • 假设 xaml 文件被命名为 AXamlPage.xaml 你会发现一个名为 AXamlFile.xaml.g.cs 的文件或类似的东西obj 目录。打开它,尝试通过放置一些断点来理解它的作用,我想你会明白的。

标签: c# xaml uwp binding inotifypropertychanged


【解决方案1】:

好像当你设置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;
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 2021-10-03
      • 1970-01-01
      • 2011-01-14
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      相关资源
      最近更新 更多