确定UIElementCollection的父级

时间:2015-12-31 16:08:44

标签: c# wpf system.reflection

我想知道是否有办法确定UIElementCollection的Parent是否属于Grid类型,最好是带反射。

UIElementCollection是一个WPF对象,例如用于Grid中的Children。 班级定义:

public class UIElementCollection : IList, ICollection, IEnumerable

网格类定义:

public class Grid : Panel, IAddChild

面板类定义:

public abstract class Panel : FrameworkElement, IAddChild
{
    public UIElementCollection Children { get; }
    // Bunch of other members...
}

修改 当前的狡猾代码:

        string visualParent = "";
        if (collection.Count == 0)
        {
            collection.Add(element);
            visualParent = VisualTreeHelper.GetParent(collection[0]).ToString();
            collection.Remove(element);
        }
        else
        {
            visualParent = VisualTreeHelper.GetParent(collection[0]).ToString();
        }

        if (!visualParent.Contains("Grid"))
        {
            throw new ArgumentException("The UIElementCollection's Parent is not a Grid. Please provide a Grid.Children UIElementCollection.");
        }

1 个答案:

答案 0 :(得分:1)

这里没有必要反思。您可以使用the is operator清除此代码,这可以检测有效的向下转换,例如从DependencyObject到Grid。您可以使用专用于此父检测操作的UIElement来消除一些if语句(意味着一个元素从未用于其他任何内容)。考虑:

var idx = collection.Add(parentDetectionElement);
var isGrid = VisualTreeHelper.GetParent(collection[idx]) is Grid;
collection.RemoveAt(idx);
if(!isGrid)
{ 
    throw new ArgumentException("The UIElementCollection's Parent is not a Grid. Please provide a Grid.Children UIElementCollection.");
}

这样更干净,避免了凌乱和潜在的错误字符串操作,它不再依赖于检查集合。但是,使用专用元素实例执行此操作非常重要,以确保它不会已经处于集合的大小。如果将其封装在函数中,则可以在本地声明新的UIElement并确保这一点。此外,封装可改善您的控制流程选项;如果需要,可以返回一个布尔值,指示父节点是否为网格,而不是抛出异常。

如果您已设置使用反射,则可以检查包含可视父级引用的不可访问属性。根据{{​​3}},它是VisualParent,它是UIElement类型。找到后,您可以检查类型,如上所示。请注意,VisualParent的访问修饰符是内部的,该类打开MS.Internal命名空间。这就是CLR可以检测父类型的原因:它们明确地设计了类以允许一般消费者禁止使用Microsoft代码功能。