我需要访问combobox的非公共成员(突出显示的项目)

我正在为应用程序实现密钥导航,并且我希望在聚焦Combo Box时覆盖空格键function,使其像enter键一样; 像这样:

if (!cb.IsDropDownOpen) { cb.IsDropDownOpen = true; } else { cb.SelectedItem = cb.{non-public member HighlightedItem}; cb.IsDropDownOpen = false; } 

问题是我需要获取该非公共成员的值,以便我可以设置所选值并关闭下拉列表(输入通常如何工作)。

现在的问题是:实现这一目标的最快和最轻松的方法是什么?

您必须使用reflection来获取属性的值

 PropertyInfo highlightedItemProperty = cb.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "HighlightedItem"); object highlightedItemValue = highlightedItemProperty.GetValue(cb, null); 

要浏览所有属性或字段,也请查看

 var allProps = cb.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(pi => pi.Name).ToList(); var allFields = cb.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(pi => pi.Name).ToList(); 

(你可以在调试器中全部阅读它们)

这是我做的一个帮助类:

 public static class PropertyHelper { ///  /// Returns a _private_ Property Value from a given Object. Uses Reflection. /// Throws a ArgumentOutOfRangeException if the Property is not found. ///  /// Type of the Property /// Object from where the Property Value is returned /// Propertyname as string. /// PropertyValue public static T GetPrivatePropertyValue(this object obj, string propName) { if (obj == null) throw new ArgumentNullException("obj"); PropertyInfo pi = obj.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (pi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Property {0} was not found in Type {1}", propName, obj.GetType().FullName)); return (T) pi.GetValue(obj, null); } ///  /// Returns a private Field Value from a given Object. Uses Reflection. /// Throws a ArgumentOutOfRangeException if the Property is not found. ///  /// Type of the Field /// Object from where the Field Value is returned /// Field Name as string. /// FieldValue public static T GetPrivateFieldValue(this object obj, string propName) { if (obj == null) throw new ArgumentNullException("obj"); Type t = obj.GetType(); FieldInfo fi = null; while (fi == null && t != null) { fi = t.GetField(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); t = t.BaseType; } if (fi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName)); return (T) fi.GetValue(obj); } ///  /// Sets a _private_ Property Value from a given Object. Uses Reflection. /// Throws a ArgumentOutOfRangeException if the Property is not found. ///  /// Type of the Property /// Object from where the Property Value is set /// Propertyname as string. /// Value to set. /// PropertyValue public static void SetPrivatePropertyValue(this object obj, string propName, T val) { Type t = obj.GetType(); if (t.GetProperty(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) == null) throw new ArgumentOutOfRangeException("propName", string.Format("Property {0} was not found in Type {1}", propName, obj.GetType().FullName)); t.InvokeMember(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, obj, new object[] {val}); } ///  /// Set a private Field Value on a given Object. Uses Reflection. ///  /// Type of the Field /// Object from where the Property Value is returned /// Field name as string. /// the value to set /// if the Property is not found public static void SetPrivateFieldValue(this object obj, string propName, T val) { if (obj == null) throw new ArgumentNullException("obj"); Type t = obj.GetType(); FieldInfo fi = null; while (fi == null && t != null) { fi = t.GetField(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); t = t.BaseType; } if (fi == null) throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName)); fi.SetValue(obj, val); } }