/// <summary> /// Required UITypeEditor override. Opens dropdown modally /// and waits for user input. /// </summary> /// <param name="context">The descriptor context. Used to retrieve /// the live instance and other data.</param> /// <param name="provider">The service provider for the given context.</param> /// <param name="value">The current property value</param> /// <returns>The updated property value, or the orignal value to effect a cancel</returns> public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService editor = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; if (editor != null) { object newObject = value; // Get the tree contents ITree tree = GetTree(context, value); // Proceed if there is anything to show // Don't check tree.VisibleItemCount. Allows the derived class to display an empty dropdown // by returning a tree with no visible elements. if (tree != null) { // Create a listbox with its events using (DropDownTreeControl treeControl = new DropDownTreeControl()) { if (UseStandardCheckBoxes) { ImageList images = new ImageList(); images.ImageSize = new Size(16, 16); treeControl.ImageList = images; treeControl.StandardCheckBoxes = true; } treeControl.BindingContextChanged += new EventHandler(HandleBindingContextChanged); treeControl.AfterDoubleClick += delegate(object sender, DoubleClickEventArgs e) { if (e.Button == MouseButtons.Left) { editor.CloseDropDown(); } }; // Manage the size of the control Size lastSize = LastControlSize; if (!lastSize.IsEmpty) { treeControl.Size = lastSize; } myInitialSelectionValue = value; // Show the dropdown. This is modal. IMultiColumnTree multiTree = tree as IMultiColumnTree; if (multiTree != null) { treeControl.MultiColumnTree = multiTree; } else { #if VISUALSTUDIO_9_0 // MSBUG: Hack workaround crashing bug in VirtualTreeControl.OnToggleExpansion treeControl.ColumnPermutation = new ColumnPermutation(1, new int[] { 0 }, false); #endif treeControl.Tree = tree; } Control adornedControl = SetTreeControlDisplayOptions(treeControl) ?? treeControl; bool escapePressed = false; EditorUtility.AttachEscapeKeyPressedEventHandler( adornedControl, delegate(object sender, EventArgs e) { escapePressed = true; }); // Make sure keystrokes are not forwarded while the modal dropdown is open IVirtualTreeInPlaceControl virtualTreeInPlaceControl = editor as IVirtualTreeInPlaceControl; VirtualTreeInPlaceControlFlags flags = virtualTreeInPlaceControl != null ? virtualTreeInPlaceControl.Flags : 0; if (0 != (flags & VirtualTreeInPlaceControlFlags.ForwardKeyEvents)) { virtualTreeInPlaceControl.Flags = flags & ~VirtualTreeInPlaceControlFlags.ForwardKeyEvents; } editor.DropDownControl(adornedControl); // Restore keystroke forwarding if (0 != (flags & VirtualTreeInPlaceControlFlags.ForwardKeyEvents)) { virtualTreeInPlaceControl.Flags = flags; } // Record the final size, we'll use it next time for this type of control LastControlSize = treeControl.Size; // Make sure the user didn't cancel, and give derived classes a chance // to translate the value displayed in the tree to an appropriately // typed value for the associated property. if (!escapePressed) { int lastRow = treeControl.LastSelectedRow; int lastColumn = treeControl.LastSelectedColumn; if (lastRow != -1 || AlwaysTranslateToValue) { newObject = TranslateToValue(context, value, tree, lastRow, lastColumn); } } } } return(newObject); } return(value); }
/// <summary> /// Required UITypeEditor override. Opens dropdown modally /// and waits for user input. /// </summary> /// <param name="context">The descriptor context. Used to retrieve /// the live instance and other data.</param> /// <param name="provider">The service provider for the given context.</param> /// <param name="value">The current property value</param> /// <returns>The updated property value, or the orignal value to effect a cancel</returns> public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService editor = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; if (editor != null) { object newObject = value; // Get the list contents and add a null handler if needed IList elements = GetContentList(context, value); string nullText = NullItemText; // Proceed if there is anything to show if (nullText != null || (elements != null && elements.Count != 0)) { // Create a tree control using (DropDownTreeControl treeControl = new DropDownTreeControl()) { #if VISUALSTUDIO_9_0 // MSBUG: Hack workaround crashing bug in VirtualTreeControl.OnToggleExpansion treeControl.ColumnPermutation = new ColumnPermutation(1, new int[] { 0 }, false); #endif // Close the dropdown after a double click treeControl.AfterDoubleClick += delegate(object sender, DoubleClickEventArgs e) { if (e.Button == MouseButtons.Left) { editor.CloseDropDown(); } }; // Create a tree for the control ITree tree = new VirtualTree(); tree.Root = new SimpleBranch(this, elements, nullText); treeControl.Tree = tree; // Manage the size of the control Size lastSize = LastControlSize; if (!lastSize.IsEmpty) { treeControl.Size = lastSize; } int initialIndex = -1; if (value != null) { if (elements != null) { initialIndex = elements.IndexOf(TranslateToDisplayObject(value, elements)); if (nullText != null) { ++initialIndex; } } } else if (nullText != null) { initialIndex = 0; } if (initialIndex != -1) { treeControl.InitialSelectionIndex = initialIndex; } Control adornedControl = SetTreeControlDisplayOptions(treeControl) ?? treeControl; bool escapePressed = false; EditorUtility.AttachEscapeKeyPressedEventHandler( adornedControl, delegate(object sender, EventArgs e) { escapePressed = true; }); // Make sure keystrokes are not forwarded while the modal dropdown is open IVirtualTreeInPlaceControl virtualTreeInPlaceControl = editor as IVirtualTreeInPlaceControl; VirtualTreeInPlaceControlFlags flags = virtualTreeInPlaceControl != null ? virtualTreeInPlaceControl.Flags : 0; if (0 != (flags & VirtualTreeInPlaceControlFlags.ForwardKeyEvents)) { virtualTreeInPlaceControl.Flags = flags & ~VirtualTreeInPlaceControlFlags.ForwardKeyEvents; } // Show the dropdown. This is modal. editor.DropDownControl(adornedControl); // Restore keystroke forwarding if (0 != (flags & VirtualTreeInPlaceControlFlags.ForwardKeyEvents)) { virtualTreeInPlaceControl.Flags = flags; } // Record the final size, we'll use it next time for this type of control LastControlSize = treeControl.Size; // Make sure the user didn't cancel, and translate the null placeholder // back to null if necessary if (!escapePressed) { int lastIndex = treeControl.AnchorIndex; if (lastIndex != -1) { if (nullText != null) { --lastIndex; if (lastIndex == -1) { newObject = null; } else { newObject = elements[lastIndex]; } } else { newObject = elements[lastIndex]; } // Give the caller the chance to change the type of the chosen object newObject = TranslateFromDisplayObject(lastIndex, newObject); } } } } return(newObject); } return(value); }