视图模型不会更新到 DataContext

View model doesn't get updated to DataContext

我有一个工作程序,其中视图模型将数据提供给视图。这是在构造函数和 Refresh() 方法中完成的,如下所示。我通常放一个 private 属性 来引用视图模型,因为我想在与它通信时省略转换。

public class TheView
{
  private ViewModel TheViewModel { get; set; }

  public TheView()
  {
    TheViewModel = new ViewModel();
    DataContext = TheViewModel;
  }

  public Refresh()
  {
    TheViewModel = new ViewModel();
    DataContext = TheViewModel;
  }
}

然后,我准备好了开始追线。由于构造函数将 DataContext 连接到 属性 TheViewModel,我想我可以只分配给后者,而前者会得到它的东西自行更新。令我失望的是,我发现事实并非如此。以下为我提供了正确的对象列表 但是 DataContext 不受影响。

public class TheView
{
  private ViewModel TheViewModel { get; set; }

  public TheView()
  {
    TheViewModel = new ViewModel();
    DataContext = TheViewModel;
  }

  public Refresh() { TheViewModel = new ViewModel(); }
}

问题是为什么会这样。或者更确切地说,如果它应该是这样的话。我在想,如果它不应该表现得像这样,也许我在代码的其他地方有问题会影响流程...

您基本上是在重新分配私有 属性,而不是 DataContext。

  1. 您创建了 TheViewModel
  2. 的实例 A
  3. 您使 DataContext 指向实例 A
  4. 您创建了 TheViewModel
  5. 的实例 B
  6. 你让 TheViewModel 私有 属性 指向实例 B
  7. DataContext 仍然指向实例 A

--> 没有理由刷新 DataContext。你没有碰它。它仍然指向仍在内存中的初始实例 A。

EDIT:

That answer was assuming the binding was using DataContext as a source, and not TheViewModel. DataContext is a DependencyProperty, whereas TheViewModel isn't. Replacing the whole view model with TheViewModel as a binding source needs to notify the view either with a dependency property or NotifyPropertyChanged

我认为您确实需要了解 DataContext 是一个依赖项 属性。

它的定义如下:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Localizability(LocalizationCategory.NeverLocalize)]
public object DataContext
{
  get
  {
    return this.GetValue(FrameworkElement.DataContextProperty);
  }
  set
  {
    this.SetValue(FrameworkElement.DataContextProperty, value);
  }
}

...

    public static readonly DependencyProperty DataContextProperty = 
DependencyProperty.Register("DataContext", typeof (object...

依赖属性比普通的 .NET 属性多,因为它们支持

  • 更改通知
  • 属性值继承
  • 决定价值的提供者

在您的情况下,"change notification" 主题很重要。

当您(重新)将一个值分配给 属性 这是一个依赖项 属性(如 DataContext)时,WPF 将自动获取此更改。在这种情况下,更改通知是在依赖 属性 的 setter 内部完成的,可以这么说。

如果您分配给 "normal" 属性 甚至私有字段,则情况并非如此(DataContext 属性 的 setter 是未调用)即使它指向 DataContext。