|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
PropertyInfo.SetValue & property walking - ReflectionI'm working on a project that requires me to set some control property values at runtime using reflection. However, I'm not sure how to achieve that when it's something like Font.Bold. I need to set the Bold property of the Font object to true or false, but not sure how to go about it. The property is presented to me in the form "Font-Bold", which is a string. I then split that value and try walking the properties, but keep running into dead ends. --so imagine that: string propertyName = "Font-Bold"; string propertyValue = "true"; control = new SomeWebControl(); Type controlType = control.GetType(); if (propertyName.IndexOf("-") > -1) { // Need to walk properties (we're looking at a property like // Font-Bold="true", which translates to control.Font.Bold) string[] propertyNames = propertyName.Split('-'); int walkCounter = 1; PropertyInfo pInfo = null; foreach (string propertyName in propertyNames) { // if first time through, then get the first PropertyInfo from the control if (walkCounter == 1) { pInfo = controlType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); } else // on subsequent iterations, get PropertyInfo from previous PropertyInfo. { pInfo = pInfo.PropertyType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); } if (pInfo == null) break; // if last property to walk, set property value. if (walkCounter == propertyNames.Length) SetProperty(pInfo, propertyName, propertyValue, control, propertyObj); walkCounter++; } } private static void SetProperty(PropertyInfo pInfo, string propertyName, string propertyValue, Control control, object objectToSetValue) { _log.EnterMethod(); System.Type pType = pInfo.PropertyType; if (pType == typeof(string)) pInfo.SetValue(objectToSetValue, propertyValue, null); else if (pType == typeof(bool)) pInfo.SetValue(objectToSetValue, Convert.ToBoolean(propertyValue), null); else if (pType == typeof(int)) pInfo.SetValue(objectToSetValue, Convert.ToInt32(propertyValue), null); //pInfo.SetValue(control, Convert.ChangeType(propertyValue, pInfo.PropertyType, CultureInfo.InvariantCulture), null); } It seems that I need to pass the object instance of Font, but not sure how to get that instance from the PropertyInfo of the control in the first place??? Any ideas would be appreciated. >However, I'm not sure how to achieve Font.Bold is a readonly property, so you can't set that with or>that when it's something like Font.Bold. without reflection. Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. The Font property is read-only. The Font.Bold property is read/write. I need
to set the Font.Bold, etc. Show quote "Mattias Sjögren" wrote: > >However, I'm not sure how to achieve > >that when it's something like Font.Bold. > > Font.Bold is a readonly property, so you can't set that with or > without reflection. > > > Mattias > > -- > Mattias Sjögren [C# MVP] mattias @ mvps.org > http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com > Please reply only to the newsgroup. > >The Font property is read-only. The Font.Bold property is read/write. I need Sorry I see now you're talking about web controls and the FontInfo>to set the Font.Bold, etc. class. I assumed Winforms and the GDI+ Font class. >>>It seems that I need to pass the object instance of Font, but not sure how You have to call pInfo.GetValue for each level. I would probably write>>>to get that instance from the PropertyInfo of the control in the first >>>place??? it something like this PropertyInfo pInfo = null; object o = control; int i = 0; Type t = controlType; for (; i < propertyNames.Length - 1; i++) { pInfo = t.GetProperty(propertyNames[i], BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); o = pInfo.GetValue(o, null);t = pInfo.PropertyType; } SetProperty(pInfo, propertyNames[i], propertyValue, control, o); Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. Thank you Mattias. I finally found a way and was coming here to post it and
saw your suggestion. I don't know if it works or not yet, but thought I'd post what does work at this point. string propertyName = "Font-Bold"; string propertyValue = "true"; control = new SomeWebControl(); Type controlType = control.GetType(); if (propertyName.IndexOf("-") > -1) { // Need to walk properties (we're looking at a property like // Font-Bold="true", which translates to control.Font.Bold) string[] propertyNames = propertyName.Split('-'); int walkCounter = 1; PropertyInfo pInfo = null; foreach (string propertyName in propertyNames) { // if first time through, then get the first PropertyInfo from the control if (walkCounter == 1) { propertyObj = controlType.InvokeMember(propertyName, BindingFlags.GetProperty, null, control, null ); pInfo = controlType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); } else // on subsequent iterations, get PropertyInfo from previous PropertyInfo. { // if not finished walking the property, then set the propertyObj again. if (walkCounter != propertyNames.Length) propertyObj = pInfo.PropertyType.InvokeMember(propertyName, BindingFlags.GetProperty, null, propertyObj, null ); pInfo = pInfo.PropertyType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public); } if (pInfo == null) break; // if last property to walk, set property value. if (walkCounter == propertyNames.Length) SetProperty(pInfo, propertyName, propertyValue, control, propertyObj); walkCounter++; } } private static void SetProperty(PropertyInfo pInfo, string propertyName, string propertyValue, Control control, object objectToSetValue) { System.Type pType = pInfo.PropertyType; if (pType == typeof(string)) pInfo.SetValue(objectToSetValue, propertyValue, null); else if (pType == typeof(bool)) pInfo.SetValue(objectToSetValue, Convert.ToBoolean(propertyValue), null); else if (pType == typeof(int)) pInfo.SetValue(objectToSetValue, Convert.ToInt32(propertyValue), null); } |
|||||||||||||||||||||||