如何检测自定义UserControl是否被应用内的VisualBrush捕获引用
实现思路
WPF 中所有依赖对象都持有非公开的 InheritanceContext / InheritanceContexts 属性,指向将当前对象作为属性值引用的父依赖对象。我们可以通过反射读取该属性,判断是否存在 VisualBrush 类型的引用方,且它的 Visual 属性正好指向当前控件。
完整实现代码
using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Media; class MyUserControl : UserControl { public bool IsInVisualBrush() { // 适配.NET Core 3.0+ 多继承上下文场景 var contextsProp = typeof(DependencyObject).GetProperty("InheritanceContexts", BindingFlags.Instance | BindingFlags.NonPublic); if (contextsProp != null) { var contexts = contextsProp.GetValue(this) as IEnumerable<DependencyObject>; if (contexts != null) { foreach (var context in contexts) { if (context is VisualBrush brush && brush.Visual == this) { return true; } } } } // 兼容.NET Framework 单继承上下文场景 var contextProp = typeof(DependencyObject).GetProperty("InheritanceContext", BindingFlags.Instance | BindingFlags.NonPublic); if (contextProp != null) { var context = contextProp.GetValue(this) as DependencyObject; if (context is VisualBrush brush && brush.Visual == this) { return true; } } return false; } }
注意事项
- 实现依赖WPF内部非公开API,不同版本WPF如果调整了继承上下文的实现逻辑可能失效,使用前需要在目标框架版本下做充分测试
- 方法必须在UI线程调用,否则会抛出WPF跨线程访问异常
- 当前实现仅检测当前控件直接作为
VisualBrush.Visual属性值的场景,如果需要检测间接引用(比如VisualBrush引用了包含当前控件的外层容器),可以递归遍历引用对象的上下文链实现。
内容的提问来源于stack exchange,提问作者lindexi
相关产品推荐
相关产品推荐

