/// <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 bind the controls 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 BindProperties(System.Windows.Forms.Control.ControlCollection controls) { Type t; PropertyInfo pi; string typeName, boundProperty; try { this.IsBinding = true; 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)) { // Find and connect the Changed event for the named property if one exists var changedEvent = t.GetEvents().Where(ev => ev.Name == customControls[typeName] + "Changed").FirstOrDefault(); if (changedEvent != null) { Delegate h; if (changedEvent.EventHandlerType == typeof(RoutedPropertyChangedEventHandler <object>)) { h = new RoutedPropertyChangedEventHandler <object>(OnWpfPropertyChanged); } else { h = new EventHandler(OnPropertyChanged); } changedEvent.RemoveEventHandler(c, h); changedEvent.AddEventHandler(c, h); } pi = t.GetProperty(customControls[typeName], BindingFlags.Public | BindingFlags.Instance); } else if (c is Label) { Label l = (Label)c; // No change event for this one but we probably don't need it pi = t.GetProperty("Content", BindingFlags.Public | BindingFlags.Instance); } else if (c is TextBoxBase) { TextBoxBase tb = (TextBoxBase)c; tb.TextChanged -= OnPropertyChanged; tb.TextChanged += OnPropertyChanged; pi = t.GetProperty("Text", BindingFlags.Public | BindingFlags.Instance); } else if (c is Selector) { Selector sel = (Selector)c; sel.SelectionChanged -= OnPropertyChanged; sel.SelectionChanged += OnPropertyChanged; pi = t.GetProperty("SelectedValue", BindingFlags.Public | BindingFlags.Instance); } else if (c is CheckBox) { CheckBox cb = (CheckBox)c; cb.Click -= OnPropertyChanged; cb.Click += OnPropertyChanged; 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.BindControlValue(boundProperty) && pi != null) { this.Bind(c, pi, boundProperty); } } } } finally { this.IsBinding = false; } }