private InstanceCreationEditor GetInstanceCreationEditor(PropertyDescriptorGridEntry entry) { if (entry is null) { return(null); } InstanceCreationEditor editor = null; // check the property type itself. this is the default path. // PropertyDescriptor pd = entry.PropertyDescriptor; if (pd != null) { editor = pd.GetEditor(typeof(InstanceCreationEditor)) as InstanceCreationEditor; } // now check if there is a dropdown UI type editor. If so, use that. // if (editor is null) { UITypeEditor ute = entry.UITypeEditor; if (ute != null && ute.GetEditStyle() == UITypeEditorEditStyle.DropDown) { editor = (InstanceCreationEditor)TypeDescriptor.GetEditor(ute, typeof(InstanceCreationEditor)); } } return(editor); }
private void OnNewLinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { InstanceCreationEditor ice = e.Link.LinkData as InstanceCreationEditor; Debug.Assert(ice != null, "How do we have a link without the InstanceCreationEditor?"); if (ice != null && gridView?.SelectedGridEntry != null) { Type createType = gridView.SelectedGridEntry.PropertyType; if (createType != null) { gridView.CloseDropDown(); object newValue = ice.CreateInstance(gridView.SelectedGridEntry, createType); if (newValue != null) { // make sure we got what we asked for. // if (!createType.IsInstanceOfType(newValue)) { throw new InvalidCastException(string.Format(SR.PropertyGridViewEditorCreatedInvalidObject, createType)); } gridView.CommitValue(newValue); } } } }
/// <summary> /// Extends CreateInstance so that methods that return a specific type object given a Type parameter can be /// used as generic method and casting is not required. /// <example> /// instancecreationeditor.CreateInstance<int>(context); /// </example> /// </summary> public static T CreateInstance <T>(this InstanceCreationEditor instancecreationeditor, ITypeDescriptorContext context) { if (instancecreationeditor == null) { throw new ArgumentNullException("instancecreationeditor"); } return((T)instancecreationeditor.CreateInstance(context, typeof(T))); }
public void SetComponent(Control ctl, bool resizable) { this.resizable = resizable; Font = gridView.Font; // check to see if we're going to be adding an InstanceCreationEditor // InstanceCreationEditor editor = (ctl is null ? null : GetInstanceCreationEditor(gridView.SelectedGridEntry as PropertyDescriptorGridEntry)); // clear any existing control we have // if (currentControl != null) { currentControl.Resize -= new EventHandler(OnCurrentControlResize); Controls.Remove(currentControl); currentControl = null; } // remove the InstanceCreationEditor link // if (createNewLink != null && createNewLink.Parent == this) { Controls.Remove(createNewLink); } // now set up the new control, top to bottom // if (ctl != null) { currentControl = ctl; Debug.WriteLineIf(CompModSwitches.DebugGridView.TraceVerbose, "DropDownHolder:SetComponent(" + (ctl.GetType().Name) + ")"); DockPadding.All = 0; // first handle the control. If it's a listbox, make sure it's got some height // to it. // if (currentControl is GridViewListBox) { ListBox lb = (ListBox)currentControl; if (lb.Items.Count == 0) { lb.Height = Math.Max(lb.Height, lb.ItemHeight); } } // Parent the control now. That way it can inherit our // font and scale itself if it wants to. try { SuspendLayout(); Controls.Add(ctl); Size sz = new Size(2 * DropDownHolderBorder + ctl.Width, 2 * DropDownHolderBorder + ctl.Height); // now check for an editor, and show the link if there is one. // if (editor != null) { // set up the link. // CreateNewLink.Text = editor.Text; CreateNewLink.Links.Clear(); CreateNewLink.Links.Add(0, editor.Text.Length, editor); // size it as close to the size of the text as possible. // int linkHeight = CreateNewLink.Height; using (Graphics g = gridView.CreateGraphics()) { SizeF sizef = PropertyGrid.MeasureTextHelper.MeasureText(gridView.OwnerGrid, g, editor.Text, gridView.GetBaseFont()); linkHeight = (int)sizef.Height; } CreateNewLink.Height = linkHeight + DropDownHolderBorder; // add the total height plus some border sz.Height += (linkHeight + (DropDownHolderBorder * 2)); } // finally, if we're resizable, add the space for the widget. // if (resizable) { sz.Height += ResizeBarSize; // we use dockpadding to save space to draw the widget. // if (resizeUp) { DockPadding.Top = ResizeBarSize; } else { DockPadding.Bottom = ResizeBarSize; } } // set the size stuff. // Size = sz; ctl.Dock = DockStyle.Fill; ctl.Visible = true; if (editor != null) { CreateNewLink.Dock = DockStyle.Bottom; Controls.Add(CreateNewLink); } } finally { ResumeLayout(true); } // hook the resize event. // currentControl.Resize += new EventHandler(OnCurrentControlResize); } Enabled = currentControl != null; }