/// <summary> /// Main UI logic function. /// </summary> /// <returns>Y axis value of the dynamic last control.</returns> protected void UpdateUI() { int lastYValue = _startingYLocation; // checkBoxEnabled.Bottom + InterControlMargin; //lastYValue = Math.Max(checkBoxEnabled.Bottom + InterControlMargin, _startingYLocation); if (this.DesignMode) { return; } // Clear existing indicator custom parameters controls. foreach (Control control in _propertiesControls) { control.Parent = null; control.Tag = null; control.Dispose(); } _propertiesControls.Clear(); if (SelectedObject == null) { OnUpdateUI(lastYValue); return; } // Gather indicator custom parameters. Type type = SelectedObject.GetType(); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); SortedDictionary <string, PropertyInfo> actualProperties = new SortedDictionary <string, PropertyInfo>(); // Filter properties. foreach (PropertyInfo info in properties) { if (_filteringPropertiesNames.Contains(info.Name) == false && info.GetCustomAttributes(typeof(HiddenAttribute), true).Length == 0) { if (actualProperties.ContainsKey(info.Name) == false) {// Also if a parent and child define same property, with "new" only show childs. actualProperties.Add(info.Name, info); } } } // Handle default properties of the SelectedObject class. foreach (PropertyInfo info in actualProperties.Values) { if (info.CanRead == false) {// We do not process write only properties. continue; } Type propertyType = info.PropertyType; bool isReadOnly = info.CanWrite == false || IsReadOnly; object value = info.GetValue(SelectedObject, null); Type underlyingType = Nullable.GetUnderlyingType(propertyType); if (underlyingType != null) {// Unwrap nullable properties. propertyType = underlyingType; if (value == null) {// Nullable enums with null values not displayed. continue; } } AddDynamicPropertyValueControl(info.Name, propertyType, value, info, isReadOnly, ref lastYValue); } // Handle dynamic generic properties of the indicator as well. if (SelectedContainerObject != null) { foreach (string name in SelectedContainerObject.GetGenericDynamicPropertiesNames()) { AddDynamicPropertyValueControl(name, SelectedContainerObject.GetGenericDynamicPropertyType(name), SelectedContainerObject.GetGenericDynamicPropertyValue(name), name, IsReadOnly, ref lastYValue); } } OnUpdateUI(lastYValue); }