【问题标题】:How to enumerate all dependency properties of control?如何枚举控件的所有依赖属性?
【发布时间】:2011-06-15 05:02:50
【问题描述】:

我有一些 WPF 控件。例如,文本框。如何枚举该控件的所有依赖属性(就像 XAML 编辑器一样)?

【问题讨论】:

    标签: wpf dependency-properties


    【解决方案1】:

    不需要使用反射(恕我直言,这是一个坏主意),因为框架已经为此提供了实用程序类(但它们并不明显:-)。

    这是基于这篇文章的答案:Enumerate BindingsLocalValueEnumerator Structure

        public static IEnumerable<DependencyProperty> EnumerateDependencyProperties(this DependencyObject obj)
        {
            if (obj != null)
            {
                LocalValueEnumerator lve = obj.GetLocalValueEnumerator();
                while (lve.MoveNext())
                {
                    yield return lve.Current.Property;
                }
            }
        }
    

    这是基于另一篇文章的另一个答案:Getting list of all dependency/attached properties of an Object 使用 MarkupWriter.GetMarkupObjectFor Method

        public static IEnumerable<DependencyProperty> EnumerateDependencyProperties(object element)
        {
            if (element != null)
            {
                MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element);
                if (markupObject != null)
                {
                    foreach (MarkupProperty mp in markupObject.Properties)
                    {
                        if (mp.DependencyProperty != null)
                            yield return mp.DependencyProperty;
                    }
                }
            }
        }
    
        public static IEnumerable<DependencyProperty> EnumerateAttachedProperties(object element)
        {
            if (element != null)
            {
                MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(element);
                if (markupObject != null)
                {
                    foreach (MarkupProperty mp in markupObject.Properties)
                    {
                        if (mp.IsAttached)
                            yield return mp.DependencyProperty;
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      试试

              var fieldInfos = typeof(TextBox).GetFields( BindingFlags.Public | BindingFlags.Static).Where(x=>x.FieldType == typeof(DependencyProperty));
              foreach (var fieldInfo in fieldInfos)
              {
                  Console.WriteLine(fieldInfo.Name);
              }
      

      【讨论】:

        【解决方案3】:

        如果你想要一个元素的 DependencyProperties 的名称,那么你可以这样做:

            var results = from prop in typeof(element).GetFields() 
                          where prop.FieldType == typeof(DependencyProperty)
                          select prop.Name.Substring(0, prop.Name.Length - 8);
        

        其中 8 是出现在依赖属性末尾的字符串“Property”的长度!

        【讨论】:

          【解决方案4】:

          您可以通过 GetFields 方法使用反射来查找 TextBox 上的所有公共静态属性。然后,您可以使用 Linq Where 子句将这些过滤到任何类型的 DependencyProperty:

            var flags = BindingFlags.Static |
                        BindingFlags.FlattenHierarchy |
                        BindingFlags.Public;
            var dependencyProperties = typeof(TextBox).GetFields(flags)
                               .Where(f => f.FieldType == typeof(DependencyProperty));
          

          然后您可以通过 Select 将其转换为名称列表:

            var dependencyProperties = typeof(TextBox).GetFields(flags)
                               .Where(f => f.FieldType == typeof(DependencyProperty))
                               .Select(dp => dp.Name);
          

          注意:每个名称都有一个“属性”后缀,如果您愿意,当然可以在上面的 Select 子句中删除它。

          【讨论】:

          • +1 表示BindingFlags.FlattenHierarchy。我的没有。
          • 这个解决方案不好。请参阅 MSDN 上的此主题:social.msdn.microsoft.com/Forums/en-US/wpf/thread/…。请参阅 Dr.WPF 的评论。
          • 关于 Dr.WPFs cmets,(1)当然,反射很慢,但这是唯一的方法,如果速度是问题,缓存结果。 (2) 上面的方法不依赖于 CLR 访问器的存在,所以这不是问题,(3) 这个方法也会找到附加的属性。
          • Colin,创建一个静态类,在该类中注册一个依赖属性作为附加属性,并将附加属性绑定到任何控件。然后通过你的代码枚举控件的依赖属性。
          【解决方案5】:
          public IList<DependencyProperty> GetAttachedProperties(DependencyObject obj)
          {
              List<DependencyProperty> result = new List<DependencyProperty>();
          
              foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(obj,
                  new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) }))
              {
                  DependencyPropertyDescriptor dpd =
                      DependencyPropertyDescriptor.FromProperty(pd);
          
                  if (dpd != null)
                  {
                      result.Add(dpd.DependencyProperty);
                  }
              }
          
              return result;
          }
          

          在这里找到:http://social.msdn.microsoft.com/Forums/en/wpf/thread/580234cb-e870-4af1-9a91-3e3ba118c89c

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-22
            • 1970-01-01
            • 2011-05-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多