ViewLocator 生成的视图在哪里以及如何分配它们的 DataContext(在 Avalonia 的 Todo 教程应用程序中)?

Where and how do the ViewLocator-generated Views get their DataContexts assigned (in Avalonia's Todo tutorial application)?

在完整的 Avalonia 教程中 Todo 应用程序 --- TodoListView 和 AddItemView 在哪里以及如何获取它们的 DataContexts 分别等于 TodoListViewModel 和 AddItemViewModel ???
我的意思是他们的父控件 MainWindow 的 DataContext 是 MainWindowViewModel 实例(在 App.xaml.cs 文件中分配)---而 MainWindow 的 Content 属性是绑定到 MainWindowViewModel 的内容 属性(它在执行期间确实获得了视图模型的分配实例)。我只是无法追踪 TodoListView 和 AddItemView 获取其 DataContexts 的来源。他们在以下时间得到它吗:

  1. 在运行时由 ViewLocator 创建? -- 但这是不可能的,因为新实例化的 View 的 DataContext 属性 在 ViewLocator returns View 实例之前仍然为 NULL -- 如已完成应用程序中以下代码的输出所示( if 块中的代码由我修改以产生所需的输出):
public IControl Build(object data)
        {
            var name = data.GetType().FullName.Replace("ViewModel", "View");
            var type = Type.GetType(name);

            if (type != null)
            {
                var viewInstance = (Control)Activator.CreateInstance(type);
                
                // the following always evaluates to true --- i.e. DataContext is always NULL before viewInstance is returned.
                if(viewInstance.DataContext == null)   
Console.WriteLine($"DataContext property of the newly created View instance of {name} in ViewLocator is NULL just before returning! ");


                 
                return  viewInstance ;
            }
            else
            {
                return new TextBlock { Text = "Not Found: " + name };
            }
        }
  1. 或者他们得到父 Window 分配的 DataContext? --- 但父 window 自己的 DataContext 是 MainWindowViewModel ----- 我们如何从 MainWindowViewModel 获取 TodoListViewModel 或 AddItemViewModel ???

简而言之,我不清楚在运行时通过 ViewLocator 生成的视图在何处分配其 DataContext 属性。


根据回答和一些搜索和播放总结了我的理解:


如果 ContentControl(在本例中为 Window 的)内容 属性 是一个控件,则该控件仅从父 ContentControl 继承 DataContext。但是如果ContentControl的Content属性是一个非Control那么ContentControl的ContentPresenter先给非Control找一个数据模板,这样就可以生成子View,然后把自己的DataContext设置给非Control .这个新分配的 DataContext 然后被新生成的子视图继承。呸呸呸!

DataContext 继承自 ContentPresenter ,它要求 IDataTemplate.Build 提供新的视图实例。当 Content 不是控件时,ContentPresenter sets its own DataContext 为子视图继承的 Content 的值。

ContentPresenter是由Windowused internally显示其Content属性.

ListBox 项也是如此。