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