我想知道是否有办法确定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.");
}
答案 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代码功能。