1

考虑以下 xaml:

<UserControl>
    <Grid x:Name="UiRoot"/>
</UserControl>

现在,在 ViewModel 中,我有一个对视图的引用(来自 Caliburn.Micro OnViewLoaded)。然后我需要确定视图是否有一个名为 UiRoot 的网格。

protected override void OnViewLoaded(object view) {
        base.OnViewLoaded(view);
    //Does the view have a UiRoot?
}

这段代码其实是在ViewModelBase中,有时候View会有一个UiRoot,有时候没有。它用于在视图确实存在时动态创建视图。

我的第一个想法是创建一个 IHasUiRoot 接口并将其放入代码隐藏中。然后我可以将它转换为 IHasUiRoot。这行得通,但由于我有一个空的代码隐藏,我想保持这种方式并通过反射或其他方式来实现。最后,我需要一个对实际控件的引用,以便动态地向它添加控件。

4

2 回答 2

1

如果您正在实现IViewAware诸如 Screen 之类的视图模型,则可以使用该IViewAware.GetView()方法(OnViewLoaded我认为IViewAware无论如何)来获取对视图的引用

然后您可以使用VisualTreeHelperorControl.FindName来获取对控件的引用:

var view = this.GetView() as Control;
if(view != null)
{
    var grid = view.FindName("UiRoot") as Grid;

    if(grid != null) // do stuff...
}
于 2013-06-28T10:41:11.797 回答
0

快速思考一下:您在 ViewModel 中添加了一种对 View 的依赖。

解决这个问题的一种方法是将代码移动到视图;让它检查自己并设置一个(依赖)属性以指向控件 UiRoot。

在 ViewModel 中,您可以添加一个类似的属性并将它们绑定到视图代码中。

这样您就可以检查/使用 ViewModel 中的属性,而无需添加 View 依赖代码。

于 2013-06-28T11:16:34.683 回答