如何在 WinUI 3 中查找有关 DependencyProperty (在 DependencyObject 上) 的 PropertyInfo

How to find PropertyInfo about a DependencyProperty (on a DependencyObject) in WinUI 3

提问人:aturnbul 提问时间:8/1/2022 更新时间:8/1/2022 访问量:278

问:

有时,拥有比元数据供应更多的信息很有用。例如,在通用跟踪方法和事件处理程序中,能够在 上找到 的名称(和其他特征)会很有帮助。DependencyPropertyDependencyPropertyDependencyObject

在 WinUI 3 中,我们使用 reports as so 来获取有关对象或类型的所有属性的包含信息(WPF 报告,我们将改用)。System.ReflectionDependencyPropertiesMemberType=PropertiesGetProperties()PropertyInfo[]DependencyPropertiesMemberType=FieldsGetFields()

DependencyProperties实际上声明为字段,并且方法通常默认不列出静态成员。调用时,请务必包含该标志,并在列表中包含 public。staticGet...ReflectionGetPropertiesBindingFlags.StaticBindingFlags.PublicDependencyProperties

接下来,我们检查每个返回的项目,看看它们是否真的与感兴趣的标识符有关。如果包含您感兴趣的标识符并且是您正在检查的项目,请使用该方法查看它们是否都引用相同的标识符(注意:如果 和 位于不同的对象上或标识不同的属性,则为 false)。返回的数组中应该有一个且只有一个匹配项。PropertyInfo[]DependencyPropertydpDependencyPropertypiPropertyInfoobject.ReferenceEquals(pi.GetValue(sender), dp)pidp

下面是一个处理程序的开头,它演示:PropertyChanged

    private static void BoundPropertyChanged(DependencyObject sender, DependencyProperty dp)
    {
        // sender is DependencyObject upon which the dp changed

        PropertyInfo dpInfo = sender.GetType().GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
            .Where(pi => pi.PropertyType == typeof(DependencyProperty) && object.ReferenceEquals(pi.GetValue(sender), dp)).Single();

        // Trace logic, etc.
    }

第一个语句有四个部分:

  1. sender.GetType().GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)获取有关 Sender 类型的所有属性的信息。从本质上讲,该标志意味着也包括继承的属性。BindingFlags.FlattenHierarchy
  2. .Where(pi => pi.PropertyType == typeof(DependencyProperty)仅选择具有 OF 的成员(路由的事件也可能在 1 的列表中)。PropertyTypeDependencyProperty
  3. && object.ReferenceEquals(pi.GetValue(sender), dp))进一步将所选项目限制为引用相同标识符的项目。
  4. 该子句选择结果列表中的唯一成员,如果多于(或少于)一个,则引发错误。.Single();

需要注意的是,这种方法严重依赖于反射,而反射相对较慢。

我不知道有更好的方法,但我欢迎建议和改进!

反射 依赖项属性 winui-3 propertyinfo

评论

0赞 Simon Mourier 8/2/2022
如果使用的是 Visual Studio,则在 .NET/C# 中,你只查看由 C#/WinRT 创建的 C# 投影 (learn.microsoft.com/en-us/windows/apps/develop/platform/...)。源实际上是 C#/WinRT 使用的 WinMD 文件。编译 WinUI3 项目时,可以在 obj 目录中看到它们(例如:Microsoft.UI.winmd、Microsoft.UI.Xaml.winmd 等)
0赞 aturnbul 8/4/2022
这看起来很有希望,但项目中似乎根本没有任何 *.winMD 文件。此外,*.winMD 文件不是 C#/WinRT 组件的编译输出吗?知道这些的来源可能在哪里吗?
0赞 Simon Mourier 8/4/2022
正如我所说,WinMD 不在项目中,编译后它们就在 obj 目录中的某个地方。我不知道来源在哪里,WinUI3 应该是开源的,但这个承诺似乎被遗忘了。
0赞 aturnbul 8/4/2022
非常感谢。我以为你的意思是项目obj目录!

答: 暂无答案