在Silverlight中获取UserControl父级的更好方法

在Silverlight中获取UserControl父级的更好方法,silverlight,Silverlight,在MainPage.xaml上,有时需要向主面板(画布)添加一个UserControl。单击该用户控件时,需要从MainPage.xaml访问一个例程—它是父控件的父控件—这将使该用户控件本身Visibility=Collapsed,或者从MainPage.xaml中一起删除 现在在我正在做的UserControl的代码后面 Dim c = VisualTreeHelper.GetParent(Me) Dim mp As MainPage = VisualTreeHelper.GetParent

在MainPage.xaml上,有时需要向主面板(画布)添加一个UserControl。单击该用户控件时,需要从MainPage.xaml访问一个例程—它是父控件的父控件—这将使该用户控件本身
Visibility=Collapsed
,或者从MainPage.xaml中一起删除

现在在我正在做的UserControl的代码后面

Dim c = VisualTreeHelper.GetParent(Me)
Dim mp As MainPage = VisualTreeHelper.GetParent(c)
mp.MyRoutine(3)

这是可行的,但它让我想知道是否有一个更直接的方式来做这件事,或更喜欢的方式。有什么想法吗?

一般来说,我会避免这种依赖。它大大降低了用户控件的实用性和灵活性

相反,在构造期间(甚至在运行时)将依赖关系推送到UserControl中可能更好。您可以传入引用
MyRoutine
的委托,或主页面实现的接口

这样,UserControl的依赖性就很明显了(因为它是API的一部分),并且可以在以后与其他应用程序/页面一起使用它


也就是说,如果您决定保留上述内容,我将至少进行一次更改。我不希望父对象的父对象总是“MainWindow”,而是递归地检查父对象,直到在类的方法中找到MainWindow(或者什么都没有)。这将至少允许您灵活地在层次结构中移动UserControl,而不会破坏它。

通过这个小框架,您可以在可视化树上执行各种查询,这是一种更通用的导航可视化树的方法。您获得家长的示例如下所示:

var parent = me.Ancestors().First();
或者,如果要查找给定类型的第一个父级

var parent = me.Ancestors<MainPage>().Cast<MainPage>().First()
var parent=me.祖先().Cast().First()

浏览可视化树的一般方法是使用自己的代码。然而,正如我在博客中所说,还有其他各种各样的实用程序可以做同样的事情。无论您使用什么,最终都会得到一组可枚举的祖先。然而,最灵活的方法是搜索
主页
类型:-

(注C)

MainPage mp=this.祖先().OfType().FirstOrDefault();

不确定这将是什么样子的VB。

这是一个有趣的界面想法。我在过去没有对interface做过太多的工作,但它值得探索。@Stan:这将使它成为一个更“可重用”的控件。现在,UserControl与您的MainWindow类紧密相连,只能在层次结构中的特定点上使用…@ColinE:这不应该是
me.祖先().Skip(1).First()?他在视觉树中上升了两个级别…使用
Cast
会产生一个异常,在这种情况下,我猜你的意思是类型
。不-我的意思是Cast。祖先返回给定类型的所有祖先,但返回的枚举类型为FrameworkElement,这是因为Linq到VisualTree扩展位于IEnumerable上,因此允许您对祖先操作的结果执行后续Linq查询。该链接不再指向Linq到VisualTree项目。
MainPage mp = this.Ancestors().OfType<MainPage>().FirstOrDefault();