【问题标题】:View model doesn't get updated to DataContext视图模型未更新为 DataContext
【发布时间】:2015-12-28 06:51:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# wpf xaml mvvm datacontext


    【解决方案1】:

    我认为您确实需要了解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 属性更多,因为它们支持

    • 更改通知
    • 属性值继承
    • 确定价值的供应商

    在您的情况下,重要的是“更改通知”主题。

    当您(重新)为依赖属性(如DataContext)的属性分配值时,WPF 将自动获取此更改。在这种情况下,更改通知是在依赖属性的设置器中完成的。

    如果您分配给“普通”属性甚至私有字段,情况并非如此(DataContext 属性的设置器不会被调用),即使它指向 DataContext。

    【讨论】:

    • 哦,对了!我将 OnPropertyChanged 用于视图模型实例 inside 的属性。我不认为视图模型本身是需要通知的可变事物。现在我又可以睡个好觉了。谢谢!
    • 只是一个旁注-知道问题中可以改进的地方吗?我得到了两次反对票,但我真的不明白为什么......
    • 这是一个很好的观点,Martin,但也许值得注意的是,只有如果他绑定到 TheViewModel 而不是使用隐式DataContext 的来源。显然是这样的:)
    • @Konrad:我的猜测是那些对你的问题投反对票的人认为这是一个非常基本的 OOP 问题,实际上它更多的是关于 DependencyProperty / NotifyPropertyChanged。如果您将 XAML 的一部分与绑定放在一起,他们就不会得出这个结论。无论如何,否决这个问题在 IMO 中是相当严厉的,尤其是懒得发表评论。别担心。
    • @Konrad:我不确定投票者是否真的理解你的问题。我猜他们只是认为“一个人不会以那种方式分配 DataContext”,但不知道确切的原因。
    【解决方案2】:

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

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

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

    编辑

    该答案假设绑定使用DataContext 作为源,而不是TheViewModelDataContext 是一个 DependencyProperty,而 TheViewModel 不是。将整个视图模型替换为 TheViewModel 作为绑定源需要使用依赖属性或 NotifyPropertyChanged 通知视图

    【讨论】:

    • 但那些是对象,所以我们谈论的是引用,而不是值。所以我想,如果 DataContext 指向与 TheViewModel 相同的内存部分,那没关系......我错过了什么?
    • 没错。您在属性中用对实例 B 的引用覆盖指向实例 A 的引用,但在数据上下文中不是。它仍然指向和以前一样的地方。我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多