考虑以下xaml:
<UserControl>
<Grid x:Name="UiRoot"/>
</UserControl>
现在,在ViewModel中,我有一个对视图的引用(来自Caliburn.Micro OnViewLoaded)。然后我需要确定View是否有一个名为UiRoot的网格。
protected override void OnViewLoaded(object view) {
base.OnViewLoaded(view);
//Does the view have a UiRoot?
}
这段代码实际上在ViewModelBase中,有时View会有一个UiRoot,有时则没有。它用于在视图存在时动态创建视图。
我的第一个想法是创建一个IHasUiRoot接口并将其放在代码隐藏中。然后我可以把它投到IHasUiRoot。这样可行,但由于我有一个空的Codebehind,我想保持这种方式并通过反射或其他方式来做。最后,我需要一个对实际控件的引用,以便动态地添加控件。
答案 0 :(得分:1)
如果您正在实施一个IViewAware
视图模型,例如屏幕,您可以使用IViewAware.GetView()
方法(我认为OnViewLoaded
IViewAware
)来获取视图
然后,您可以使用VisualTreeHelper
或Control.FindName
来获取对该控件的引用:
var view = this.GetView() as Control;
if(view != null)
{
var grid = view.FindName("UiRoot") as Grid;
if(grid != null) // do stuff...
}
答案 1 :(得分:0)
只是一个简单的想法:你在ViewModel中添加了一种对View的依赖。
解决这个问题的一种方法是将代码移动到View;让它检查自己并设置(依赖)属性以指向控件UiRoot。
在ViewModel中,您可以添加一个类似的属性并在视图代码中绑定它们。
这样,您可以在ViewModel中检查/使用该属性,而无需添加View依赖代码。