问题描述:
新建了一个自定义控件,叫 PortPage,还有它对应的PortPageViewModel

我在一个父窗体 MachineControl 中,想保存一个PortPageViewModel类型的属性,属性的定义是下面这样
xaml中这样写,直接把PortPage当成控件:

然后在的窗体代码 MachineControl.xaml.cs中实现绑定这个用户控件的数据绑定;

PortPage.xaml.cs定义如下,因为使用了ReactiveUI框架,继承了IViewFor<PortPageViewModel>接口,所以他有PortPageViewModel类型的ViewModel属性。

运行起来之后发现在用户控件上,按钮的命令是绑定状态,但是像DataGrid,TextBox这类控件并没有绑定效果
它们的区别是:命令的绑定我是通过后端代码实现:

控件的绑定我是通过在前端指定:

出现这种前端绑定失效问题首先应该联想到窗体的DataContext属性有没有正确设置;
解决办法:
尝试1:
很遗憾,在前端尝试指定DataContext属性并没有解决这个问题:

查阅资料后,知道通过d:DataContext 只在 设计器(Visual Studio Designer) 中生效,在运行时完全不起作用。
d:DataContext只影响设计器,不影响运行时
尝试2:

这种方法运行后看似可以绑定,但是我发现他会进入PortPageViewModel的构造函数两次第一次是在父窗体中的实例化,

第二次是在PortPage控件的初始化方法中:

这就有一个新的问题,我界面上的DataGrid,TextBox这类控件到底绑定了哪一个ViewModel;
为了验证,我在PortPageViewModel中添加了一个string类型的test字段;然后在构造函数中设置为"ctor":

并且第一次new PortPageViewModel之后,把test赋值为"new";
这样就满足了第一个VM的test是"new",第二个VM的test是"ctor";
然后在PortPage的构造函数,绑定按钮命令前添加了以下两行代码,用于获取前端控件绑定的ViewModel的 test属性;运行结果如下:

说明了前端容器控件和前端按钮绑定了两个不同的VewModel,分别是我上面所提到的两个PortPageViewModel对象。
这个尝试也不行;
尝试3:
然后查阅资料后,通过下面的方法指定可以实现正常绑定:

在给用户控件的ViewModel属性赋值时,顺便在后端设置DataContext属性;
验证如下:

而这又引出一个新问题:关于DataContext的设置方式的区别
未完,或者新写一篇文章。得闲研究