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