/// <summary> /// Given the specified key-Type mapping of required editors, this method /// will dispose all currently active editors that are no longer needed. /// </summary> /// <param name="requiredEditors"></param> private void DisposeObsoleteEditors(IReadOnlyDictionary <string, Type> requiredEditors) { // Gather all property editors for keys we no longer need or that don't match the required type. List <string> obsoleteParameterEditors = new List <string>(); foreach (var pair in this.parameterEditors) { Type requiredType; if (requiredEditors.TryGetValue(pair.Key, out requiredType)) { if (pair.Value.EditedType == requiredType) { continue; } } obsoleteParameterEditors.Add(pair.Key); } // Dispose all previously gathered editors. This is a two-step process, // because we can't modify a collection while iterating it. foreach (string key in obsoleteParameterEditors) { PropertyEditor editor = this.parameterEditors[key]; this.parameterEditors.Remove(key); this.RemovePropertyEditor(editor); editor.Dispose(); } }
protected void UpdateElementEditors(IList[] values) { PropertyInfo indexer = typeof(IList).GetProperty("Item"); int visibleElementCount = values.Where(o => o != null).Min(o => (int)o.Count); bool showOffset = false; if (visibleElementCount > 10) { this.offset = Math.Min(this.offset, visibleElementCount - 10); this.offsetEditor.Maximum = visibleElementCount - 10; visibleElementCount = 10; showOffset = true; } else { this.offset = 0; } if (this.sizeEditor.ParentEditor == null) { this.AddPropertyEditor(this.sizeEditor, 0); } if (showOffset && this.offsetEditor.ParentEditor == null) { this.AddPropertyEditor(this.offsetEditor, 1); } else if (!showOffset && this.offsetEditor.ParentEditor != null) { this.RemovePropertyEditor(this.offsetEditor); } this.internalEditors = showOffset ? 2 : 1; this.BeginUpdate(); // Add missing editors Type elementType = GetIListElementType(this.EditedType); Type reflectedArrayType = PropertyEditor.ReflectDynamicType(elementType, values.Select(a => GetIListElementType(a.GetType()))); for (int i = this.internalEditors; i < visibleElementCount + this.internalEditors; i++) { int elementIndex = i - this.internalEditors + this.offset; Type reflectedElementType = PropertyEditor.ReflectDynamicType( reflectedArrayType, values.Where(v => v != null).Select(v => indexer.GetValue(v, new object[] { elementIndex }))); PropertyEditor elementEditor; // Retrieve and Update existing editor if (i < this.Children.Count()) { elementEditor = this.Children.ElementAt(i); if (elementEditor.EditedType != reflectedElementType) { // If the editor has the wrong type, we'll need to create a new one PropertyEditor oldEditor = elementEditor; elementEditor = this.ParentGrid.CreateEditor(reflectedElementType, this); this.AddPropertyEditor(elementEditor, oldEditor); this.RemovePropertyEditor(oldEditor); oldEditor.Dispose(); this.ParentGrid.ConfigureEditor(elementEditor); } } // Create a new editor else { elementEditor = this.ParentGrid.CreateEditor(reflectedElementType, this); this.AddPropertyEditor(elementEditor); this.ParentGrid.ConfigureEditor(elementEditor); } elementEditor.Getter = this.CreateElementValueGetter(indexer, elementIndex); elementEditor.Setter = this.CreateElementValueSetter(indexer, elementIndex); elementEditor.PropertyName = "[" + elementIndex + "]"; } // Remove overflowing editors for (int i = this.Children.Count() - (this.internalEditors + 1); i >= visibleElementCount; i--) { PropertyEditor child = this.Children.Last(); this.RemovePropertyEditor(child); } this.EndUpdate(); }
protected void UpdateElementEditors(IDictionary[] values) { PropertyInfo indexer = typeof(IDictionary).GetProperty("Item"); int visibleElementCount = values.Where(o => o != null).Min(o => (int)o.Count); bool showOffset = false; if (visibleElementCount > 10) { this.offset = Math.Min(this.offset, visibleElementCount - 10); this.offsetEditor.Maximum = visibleElementCount - 10; visibleElementCount = 10; showOffset = true; } else { this.offset = 0; } if (this.addKeyEditor.ParentEditor == null) { this.AddPropertyEditor(this.addKeyEditor, 0); } if (showOffset && this.offsetEditor.ParentEditor == null) { this.AddPropertyEditor(this.offsetEditor, 1); } else if (!showOffset && this.offsetEditor.ParentEditor != null) { this.RemovePropertyEditor(this.offsetEditor); } this.internalEditors = showOffset ? 2 : 1; // Determine which keys are currently displayed int elemIndex = 0; this.displayedKeys = new object[visibleElementCount]; foreach (object key in values.Where(o => o != null).First().Keys) { if (elemIndex >= this.offset) { this.displayedKeys[elemIndex - this.offset] = key; } elemIndex++; if (elemIndex >= this.offset + visibleElementCount) { break; } } this.BeginUpdate(); // Add missing editors Type dictValueType = GetIDictionaryValueType(this.EditedType); Type reflectedDictValueType = PropertyEditor.ReflectDynamicType(dictValueType, values.Select(a => GetIDictionaryValueType(a.GetType()))); for (int i = this.internalEditors; i < visibleElementCount + this.internalEditors; i++) { object elementKey = this.displayedKeys[i - this.internalEditors]; Type reflectedElementValueType = PropertyEditor.ReflectDynamicType( reflectedDictValueType, values.Where(v => v != null).Select(v => indexer.GetValue(v, new object[] { elementKey }))); PropertyEditor elementEditor; // Retrieve and Update existing editor if (i < this.Children.Count()) { elementEditor = this.Children.ElementAt(i); if (elementEditor.EditedType != reflectedElementValueType) { // If the editor has the wrong type, we'll need to create a new one PropertyEditor oldEditor = elementEditor; elementEditor = this.ParentGrid.CreateEditor(reflectedElementValueType, this); this.AddPropertyEditor(elementEditor, oldEditor); this.RemovePropertyEditor(oldEditor); oldEditor.Dispose(); this.ParentGrid.ConfigureEditor(elementEditor); } } // Create a new editor else { elementEditor = this.ParentGrid.CreateEditor(reflectedElementValueType, this); this.AddPropertyEditor(elementEditor); this.ParentGrid.ConfigureEditor(elementEditor); if (!elementEditor.Hints.HasFlag(HintFlags.HasButton)) { elementEditor.Hints |= HintFlags.HasButton | HintFlags.ButtonEnabled; elementEditor.ButtonPressed += this.elementEditor_ButtonPressed; } } elementEditor.Getter = this.CreateElementValueGetter(indexer, elementKey); elementEditor.Setter = this.CreateElementValueSetter(indexer, elementKey); elementEditor.PropertyName = "[" + elementKey.ToString() + "]"; } // Remove overflowing editors for (int i = this.Children.Count() - (this.internalEditors + 1); i >= visibleElementCount; i--) { PropertyEditor child = this.Children.Last(); this.RemovePropertyEditor(child); child.ButtonPressed -= this.elementEditor_ButtonPressed; } this.EndUpdate(); }