/// <summary> /// This is used to store the control values in the given collection to their associated project /// properties. /// </summary> /// <param name="controls">The control collection from which to get the bound controls. WPF controls and /// their children in an <see cref="ElementHost"/> are bound if they declare a property name using the /// <see cref="P:SandcastleBuilder.WPF.PropertyPages.PropertyPageBinding.ProjectPropertyName"/> attached /// property.</param> protected void StoreProperties(System.Windows.Forms.Control.ControlCollection controls) { Type t; PropertyInfo pi; object controlValue; string typeName, boundProperty, propValue; foreach (var control in controls.OfType <ElementHost>().Select(h => (FrameworkElement)h.Child)) { foreach (var c in control.AllChildElements().Where(c => !String.IsNullOrWhiteSpace(PropertyPageBinding.GetProjectPropertyName(c)))) { t = c.GetType(); typeName = t.FullName; boundProperty = PropertyPageBinding.GetProjectPropertyName(c); // Check for custom types first if (customControls.ContainsKey(typeName)) { pi = t.GetProperty(customControls[typeName], BindingFlags.Public | BindingFlags.Instance); } else if (c is TextBoxBase) { pi = t.GetProperty("Text", BindingFlags.Public | BindingFlags.Instance); } else if (c is Selector) { pi = t.GetProperty("SelectedValue", BindingFlags.Public | BindingFlags.Instance); } else if (c is CheckBox) { pi = t.GetProperty("IsChecked", BindingFlags.Public | BindingFlags.Instance); } else { pi = null; } // Give the user a chance to handle the control in a custom fashion. If not handled and we // couldn't figure out what to use, ignore it. if (!this.StoreControlValue(boundProperty) && pi != null) { controlValue = pi.GetValue(c, null); if (controlValue == null) { propValue = String.Empty; } else { propValue = controlValue.ToString(); } // If the string is empty and the property doesn't exist, don't create it unnecessarily if (propValue.Length != 0 || this.CurrentProject.MSBuildProject.GetProperty(boundProperty) != null) { if (this.IsEscapedProperty(boundProperty)) { propValue = EscapeValueAttribute.Escape(propValue); } this.CurrentProject.MSBuildProject.SetProperty(boundProperty, propValue); } } } } }
/// <summary> /// This is used to store the control values in the given collection to their associated project /// properties. /// </summary> /// <param name="controls">The control collection from which to get the values. Controls are bound if /// their <see cref="Control.Tag"/> property is a string that matches a project property.</param> /// <remarks>This method is recursive</remarks> protected void StoreProperties(Control.ControlCollection controls) { Type t; PropertyInfo pi; object controlValue; string typeName, boundProperty, propValue; foreach (Control c in controls) { t = c.GetType(); typeName = t.FullName; boundProperty = c.Tag as string; // Ignore unbound controls if (String.IsNullOrEmpty(boundProperty)) { // Scan containers too except for user controls unless they are in the custom user control // list. They may or may not represent a single-valued item and we can't process them // reliably. The same could be true of one of these if it's a derived type. if (!customControls.ContainsKey(typeName) && (c is GroupBox || c is Panel || c is TabControl || c is TabPage || c is SplitContainer || customUserControls.Contains(typeName))) { this.StoreProperties(c.Controls); } continue; } // Check for custom types first if (customControls.ContainsKey(typeName)) { pi = t.GetProperty(customControls[typeName], BindingFlags.Public | BindingFlags.Instance); } else if (c is TextBoxBase || c is Label) { pi = t.GetProperty("Text", BindingFlags.Public | BindingFlags.Instance); } else if (c is ComboBox) { if (((ComboBox)c).DataSource != null) { pi = t.GetProperty("SelectedValue", BindingFlags.Public | BindingFlags.Instance); } else { pi = t.GetProperty("SelectedItem", BindingFlags.Public | BindingFlags.Instance); } } else if (c is CheckBox) { pi = t.GetProperty("Checked", BindingFlags.Public | BindingFlags.Instance); } else if ((c is DateTimePicker) || (c is UpDownBase) || (c is TrackBar)) { pi = t.GetProperty("Value", BindingFlags.Public | BindingFlags.Instance); } else if (c is ListBox) { if (((ListBox)c).DataSource != null) { pi = t.GetProperty("SelectedValue", BindingFlags.Public | BindingFlags.Instance); } else { pi = t.GetProperty("SelectedItem", BindingFlags.Public | BindingFlags.Instance); } } else { pi = null; } // Note that CheckedListBox is not handled here since it is most likely multi-valued. The // user must store it in the StoreControLValue() method override. // Give the user a chance to handle the control in a custom fashion. If not handled and we // couldn't figure out what to use, ignore it. if (!this.StoreControlValue(c) && pi != null) { controlValue = pi.GetValue(c, null); if (controlValue == null) { propValue = String.Empty; } else { propValue = controlValue.ToString(); } // If the string is empty and the property doesn't exist, don't create it unnecessarily if (propValue.Length != 0 || this.CurrentProject.MSBuildProject.GetProperty(boundProperty) != null) { if (this.IsEscapedProperty(boundProperty)) { propValue = EscapeValueAttribute.Escape(propValue); } this.CurrentProject.MSBuildProject.SetProperty(boundProperty, propValue); } } } }
/// <summary> /// Bind the control to the property value by setting the property to the current value from the project /// </summary> /// <param name="control">The control to bind</param> /// <param name="propertyInfo">The property information</param> /// <param name="boundProperty">The project property name</param> private void Bind(object control, PropertyInfo propertyInfo, string boundProperty) { string propValue = null; object controlValue; if (this.CurrentProject != null) { var projProp = this.CurrentProject.MSBuildProject.GetProperty(boundProperty); if (projProp != null) { propValue = projProp.UnevaluatedValue; } // If null, the property probably doesn't exist so ignore it if (propValue == null) { return; } if (this.IsEscapedProperty(boundProperty)) { propValue = EscapeValueAttribute.Unescape(propValue); } TypeCode typeCode = Type.GetTypeCode(propertyInfo.PropertyType); // If it's something like a nullable type, get the type parameter type code if (typeCode == TypeCode.Object && propertyInfo.PropertyType.GenericTypeArguments.Length != 0) { typeCode = Type.GetTypeCode(propertyInfo.PropertyType.GenericTypeArguments[0]); } // Set the value based on the type switch (typeCode) { case TypeCode.Object: case TypeCode.String: controlValue = propValue; break; case TypeCode.Char: controlValue = propValue[0]; break; case TypeCode.Byte: controlValue = Convert.ToByte(propValue[0]); break; case TypeCode.SByte: controlValue = Convert.ToSByte(propValue[0]); break; case TypeCode.Decimal: controlValue = Convert.ToDecimal(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Double: controlValue = Convert.ToDouble(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Single: controlValue = Convert.ToSingle(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Int16: controlValue = Convert.ToInt16(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Int32: controlValue = Convert.ToInt32(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Int64: controlValue = Convert.ToInt64(propValue, CultureInfo.CurrentCulture); break; case TypeCode.UInt16: controlValue = Convert.ToUInt16(propValue, CultureInfo.CurrentCulture); break; case TypeCode.UInt32: controlValue = Convert.ToUInt32(propValue, CultureInfo.CurrentCulture); break; case TypeCode.UInt64: controlValue = Convert.ToUInt64(propValue, CultureInfo.CurrentCulture); break; case TypeCode.Boolean: controlValue = Convert.ToBoolean(propValue, CultureInfo.CurrentCulture); break; case TypeCode.DateTime: controlValue = Convert.ToDateTime(propValue, CultureInfo.CurrentCulture); break; default: // Ignore unknown types return; } propertyInfo.SetValue(control, controlValue, null); } }
/// <summary> /// Bind the control to the property value by setting the property to the current value from the project /// </summary> /// <param name="control">The control to bind</param> /// <param name="propertyInfo">The property information</param> /// <param name="boundProperty">The project property name</param> private void Bind(Control control, PropertyInfo propertyInfo, string boundProperty) { string propValue = null; object controlValue; if (this.CurrentProject != null) { var projProp = this.CurrentProject.MSBuildProject.GetProperty(boundProperty); if (projProp != null) { propValue = projProp.UnevaluatedValue; } // If null, the property probably doesn't exist so ignore it if (propValue == null) { return; } if (this.IsEscapedProperty(boundProperty)) { propValue = EscapeValueAttribute.Unescape(propValue); } // Set the value based on the type switch (Type.GetTypeCode(propertyInfo.PropertyType)) { case TypeCode.Object: case TypeCode.String: controlValue = (propValue ?? String.Empty); break; case TypeCode.Char: controlValue = (propValue != null) ? propValue[0] : '\x0'; break; case TypeCode.Byte: controlValue = (propValue != null) ? Convert.ToByte(propValue[0]) : 0; break; case TypeCode.SByte: controlValue = (propValue != null) ? Convert.ToSByte(propValue[0]) : 0; break; case TypeCode.Decimal: controlValue = (propValue != null) ? Convert.ToDecimal(propValue, CultureInfo.CurrentCulture) : 0m; break; case TypeCode.Double: controlValue = (propValue != null) ? Convert.ToDouble(propValue, CultureInfo.CurrentCulture) : 0d; break; case TypeCode.Single: controlValue = (propValue != null) ? Convert.ToSingle(propValue, CultureInfo.CurrentCulture) : 0f; break; case TypeCode.Int16: controlValue = (propValue != null) ? Convert.ToInt16(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.Int32: controlValue = (propValue != null) ? Convert.ToInt32(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.Int64: controlValue = (propValue != null) ? Convert.ToInt64(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.UInt16: controlValue = (propValue != null) ? Convert.ToUInt16(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.UInt32: controlValue = (propValue != null) ? Convert.ToUInt32(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.UInt64: controlValue = (propValue != null) ? Convert.ToUInt64(propValue, CultureInfo.CurrentCulture) : 0; break; case TypeCode.Boolean: controlValue = (propValue != null) ? Convert.ToBoolean(propValue, CultureInfo.CurrentCulture) : false; break; case TypeCode.DateTime: controlValue = (propValue != null) ? Convert.ToDateTime(propValue, CultureInfo.CurrentCulture) : DateTime.Today; break; default: // Ignore unknown types return; } propertyInfo.SetValue(control, controlValue, null); } }