我需要访问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); } }