/// <summary> /// Edits the specified object's value using the editor style indicated by GetEditStyle. /// </summary> /// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param> /// <param name="provider">An IServiceProvider that this editor can use to obtain services.</param> /// <param name="value">The object to edit.</param> /// <returns></returns> public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if ((context != null) && (context.Instance != null) && (provider != null)) { // Convert to the correct class. CommandBaseCollection commands = value as CommandBaseCollection; // Create the dialog used to edit the commands CommandCollectionDialog dialog = new CommandCollectionDialog(commands); // Give user the chance to modify the nodes if (dialog.ShowDialog() == DialogResult.OK) { // Reflect changes back into original copy and generate appropriate // component changes to designer to reflect these changes SynchronizeCollections(commands, dialog.Commands, context); // Notify container that value has been changed context.OnComponentChanged(); } } // Return the original value return(value); }
/// <summary> /// Initializes a new instance of the NodeCollectionDialog class. /// </summary> /// <param name="original">Original Nodes to be edited.</param> public CommandCollectionDialog(CommandBaseCollection original) { // Required for Windows Form Designer support InitializeComponent(); // Create a new per command foreach (CommandBase command in original) { // Create a new tree node to hold the command Node newNode = new Node(); // Create a copy to attach to the node CommandBase copy = (CommandBase)command.Clone(); if (copy.GetType() == typeof(SeparatorCommand)) { newNode.Text = "(Separator)"; } else if (copy.GetType() == typeof(ButtonCommand)) { ButtonCommand button = copy as ButtonCommand; // Special case the absense of text if (button.Text.Length == 0) { newNode.Text = "<Empty>"; } else { newNode.Text = button.Text; } // We want to know when the text for the node changes button.TextChanged += new EventHandler(OnTextChanged); } // Attached a copy of the command to the node newNode.Tag = copy; // Append to end of the list treeControl1.Nodes.Add(newNode); } // Set correct initial state of the buttons UpdateButtonState(); }
private void InternalConstruct() { // Create internal state objects _details = new CommandDetails(this); _engine = new SingleLayoutEngine(); _states = new CommandStateCollection(); _padding = new Padding(); // Define state _initCount = 0; _layoutRequired = false; _mouseDownButton = MouseButtons.None; _mouseCapture = false; _currentCmdState = null; _tooltipCmdState = null; // Hook into padding changed events _padding.PaddingChanged += new EventHandler(OnPaddingChanged); // Create exposed/internal collections of commands _externals = new CommandBaseCollection(); _internals = new CommandBaseCollection(); // Hook into command collection modifications _externals.Clearing += new CollectionClear(OnCommandsClearing); _externals.Cleared += new CollectionClear(OnCommandsCleared); _externals.Inserted += new CollectionChange(OnCommandInserted); _externals.Removed += new CollectionChange(OnCommandRemoved); _internals.Clearing += new CollectionClear(OnCommandsClearing); _internals.Cleared += new CollectionClear(OnCommandsCleared); _internals.Inserted += new CollectionChange(OnCommandInserted); _internals.Removed += new CollectionChange(OnCommandRemoved); // Need a timer so that when the mouse hovers we can show tooltips _hoverTimer = new Timer(); _hoverTimer.Tick += new EventHandler(OnMouseHoverTick); // Need a timer so that we can send updates to top level commands _updateTimer = new Timer(); _updateTimer.Tick += new EventHandler(OnUpdateTick); }
private void SynchronizeCollections(CommandBaseCollection orig, CommandBaseCollection copy, ITypeDescriptorContext context) { // Make a note of all original commands that are still in copy Hashtable both = new Hashtable(); // First pass, scan looking for commands that are in original and copy foreach (CommandBase copyCommand in copy) { // Does this node have an back pointer to its original? if (copyCommand.Original != null) { // Then make a note that it is in both collections both.Add(copyCommand.Original, copyCommand.Original); // Update the original from the copy copyCommand.Original.UpdateInstance(copyCommand); } } int origCount = orig.Count; // Second pass, remove commands in the original but not in the copy for (int i = 0; i < origCount; i++) { // Get access to the indexed command from original CommandBase origCommand = orig[i]; // If not in the found collection... if (!both.ContainsKey(origCommand)) { // ...then it has been removed from the copy, so delete it orig.Remove(origCommand); // Must remove from context container so it is removed from designer tray context.Container.Remove(origCommand as IComponent); // Reduce the count and index to reflect change in collection contents --i; --origCount; } } int copyCount = copy.Count; // Third pass, add new nodes from copy but not in original for (int i = 0; i < copyCount; i++) { // Get access to the indexed command from copy CommandBase copyCommand = copy[i]; // If this command is a new one then it will not have an 'original' property if (copyCommand.Original == null) { // It references itself in the new collection copyCommand.Original = copyCommand; // Add this node into the original at indexed position orig.Insert(i, copyCommand); // Must add into context container so it is added to the designer tray context.Container.Add(copyCommand as IComponent); } } // Fourth pass, set correct ordering to match copy for (int i = 0; i < copyCount; i++) { // Grab indexed item from the copy CommandBase copyCommand = copy[i]; // Get the command to look for in original CommandBase origCommand = copyCommand.Original; // Find its indexed position in original collection int origIndex = orig.IndexOf(origCommand); // If this is not its required position if (origIndex != i) { // Remove it from collection orig.Remove(origCommand); // Insert back in correct place orig.Insert(i, origCommand); } } }