为何注入的WPF ViewModel在ContentControl中不显示,仅重新初始化后可见?
我使用如下ContentControl:
<ContentControl x:Name="GraphArea" s:View.Model="{Binding SelectedViewModel}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" />
它绑定到ViewModel中的如下属性:
private Screen selectedViewModel; public Screen SelectedViewModel { get { return selectedViewModel; } set{SetAndNotify(ref this.selectedViewModel, value);} }
我通过Stylet注入了第二个名为GisViewModel的ViewModel:
[Inject] public GisViewModel GisViewModel { get; set; }
随后将注入的GisViewModel赋值给SelectedViewModel属性:
public void LoadMap() { SelectedViewModel = GisViewModel; }
但此时ContentControl中没有任何内容显示。不过如果直接新建实例,ContentControl可以正常加载内容:
public void LoadMap() { SelectedViewModel = new GisViewModel(); }
为何新建初始化的GisViewModel能正常显示,而注入的版本却不行?
以下是几种可能导致注入实例无法显示的原因及对应解决办法:
Stylet视图绑定规则限制
Stylet默认通过ViewModel的原始类型匹配对应View,若注入的GisViewModel被IoC容器生成了代理类(比如用于AOP拦截),其实际类型会变成代理子类而非原始的GisViewModel,导致Stylet找不到关联的View。可以通过调试输出检查实例类型:Debug.WriteLine(GisViewModel.GetType().FullName);如果输出是代理类(例如带有
DynamicProxy后缀),需要配置容器保留原始类型元数据,或者手动在GisViewModel上添加[View(typeof(GisView))]特性指定视图关联。注入实例未完成初始化
手动新建实例时,构造函数会同步执行所有初始化逻辑;但通过IoC容器注入时,若GisViewModel的构造函数依赖其他服务,可能存在依赖注入未完成、或延迟初始化逻辑未触发的情况。检查GisViewModel的构造函数,确保所有依赖都被正确注入,或者在赋值前手动调用初始化方法。IoC容器生命周期配置错误
如果GisViewModel被配置为错误的生命周期(例如单例但未被正确实例化,或瞬态实例被提前回收),会导致赋值的实例处于无效状态。检查Stylet的IoC容器配置,确保GisViewModel的生命周期设置合理(比如Singleton或Transient),且容器在赋值时已完成该实例的创建。视图关联特性缺失
若手动新建实例时,View与ViewModel的关联是通过特性实现的,但注入的实例所在类未添加对应特性,也会导致Stylet无法匹配视图。确认GisViewModel类上是否添加了[View(typeof(GisView))]特性,且特性中指定的View类型正确。
内容的提问来源于stack exchange,提问作者Richard

