在完成的 Avalonia 教程 Todo 应用程序中 --- TodoListView 和 AddItemView 在哪里以及如何获取它们的 DataContexts 以分别等于 TodoListViewModel 和 AddItemViewModel ???
我的意思是他们的父控件 MainWindow 的 DataContext 是一个 MainWindowViewModel 实例(在 App.xaml.cs 文件中分配)---而 MainWindow 的 Content 属性绑定到 MainWindowViewModel 的 Content 属性(在执行期间它确实获得了视图模型的分配实例)。我只是无法追踪 TodoListView 和 AddItemView 获取其 DataContexts 的来源。他们是否在以下情况下得到它:
- 由 ViewLocator 在运行时创建?-- 但这是不可能的,因为在 ViewLocator 返回 View 实例之前,新实例化的 View 的 DataContext 属性仍然为 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 ?--- 但是父窗口自己的 DataContext 是 MainWindowViewModel ----- 我们如何从 MainWindowViewModel 到 TodoListViewModel 或 AddItemViewModel ???
简而言之,我不清楚在运行时通过 ViewLocator 生成的视图在哪里分配了它们的 DataContext 属性。
总结一下我从答案和一些搜索和游戏中理解的内容:
如果 ContentControl(在本例中为 Window)的 Content 属性是 Control,则 Control 只需从父 ContentControl 继承 DataContext。但是如果ContentControl的Content属性是non-Control,那么ContentControl的ContentPresenter首先会为non-Control找到一个数据模板,这样就可以生成一个子View,然后将自己的DataContext设置为non-Control。这个新分配的 DataContext 然后被新生成的子 View 继承。呸呸呸!