Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Undo functionality for Node rename in TreeView

Undo functionality for Node rename in TreeView

Scheduled Pinned Locked Moved C#
question
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nyanoba
    wrote on last edited by
    #1

    I Implemented the Rename Functionality, But can some one tells me the good way to implement the Undo Functionality for rename?

    B B 2 Replies Last reply
    0
    • N Nyanoba

      I Implemented the Rename Functionality, But can some one tells me the good way to implement the Undo Functionality for rename?

      B Offline
      B Offline
      BillWoodruff
      wrote on last edited by
      #2

      How about clarifying the scenario here: 1. is this a WinForms question, and are you using the standard WinForms TreeView provided by MS ? 2. For 'Undo:' are you talking about one level of Undo, or many levels, or levels set by the end-user while running the Application ? best, Bill

      "Beauty is in the eye of the beholder, and it may be necessary from time to time to give a stupid or misinformed beholder a black eye." Miss Piggy"

      1 Reply Last reply
      0
      • N Nyanoba

        I Implemented the Rename Functionality, But can some one tells me the good way to implement the Undo Functionality for rename?

        B Offline
        B Offline
        BobJanova
        wrote on last edited by
        #3

        You shouldn't 'implement the Undo Functionality for rename'. You should implement undo as an app-wide thing which maintains a stack of commands across the whole application and knows how to undo them. There's two ways to do undo: either you maintain the state before each operation, or you store each operation as a command which knows how to undo itself. In all but the simplest case you want to do the second way. You need to implement every action within your application as a command, where command means something like:

        interface IUndoableCommand {
        void Undo();
        void Redo();
        }

        In this case, assuming your tree view is bound to some view-model level property, you would hook the NodeRenamed event (whatever it's actually called) - pseudocode:

        class ItemRenameCommand : IUndoableCommand {
        string oldname, newname;
        INamedModel Model { get; set; }

        ItemRenameCommand(INamedModel model, string oldname, string newname) {
        this.oldname = oldname; this.newname = newname;
        Model = model;
        }

        void Undo() { Model.Name = oldname; }
        void Redo() { Model.Name = newname; }
        }

        class MainForm : Form {
        ...
        void TreeNodeRenamed(object sender, NodeRenameEventArgs e){
        IUndoableCommand renameCommand = new ItemRenameCommand(treeViewModel, e.OldName, e.NewName);
        undoStack.Push(renameCommand);
        }

        Stack<IUndoableCommand> undoStack, redoStack;
        }

        (Remember, pseudocode; I can't remember how you actually hook onto the rename event of a TreeView, and it's not really the main point of the discussion, but it means that won't compile.) INamedModel is just for the Name property, you'd typically have all your view model classes implement something like that in a strongly typed environment. One can have an argument about whether the undo/redo stacks should be in the UI (i.e. the view) or the view-model, taking a MVVM approach to structure. I tend to feel that because it represents user actions, it is part of the view. Then, to undo, you take items off the undo stack and call .Undo() on each of them in turn, pushing them onto the redo stack. And to redo, you take items off the redo stack, move them to the undo stack and call .Redo() on each one. The tricky bit is making sure that everything can be represented by a reversible command. For some things (simplistic example, a Reset or Randomise button) you will have to store most or all of the previous state, but avoid doing that in all cases where it is possible to do so, as storing the whole state for each undo entry is a

        B N 2 Replies Last reply
        0
        • B BobJanova

          You shouldn't 'implement the Undo Functionality for rename'. You should implement undo as an app-wide thing which maintains a stack of commands across the whole application and knows how to undo them. There's two ways to do undo: either you maintain the state before each operation, or you store each operation as a command which knows how to undo itself. In all but the simplest case you want to do the second way. You need to implement every action within your application as a command, where command means something like:

          interface IUndoableCommand {
          void Undo();
          void Redo();
          }

          In this case, assuming your tree view is bound to some view-model level property, you would hook the NodeRenamed event (whatever it's actually called) - pseudocode:

          class ItemRenameCommand : IUndoableCommand {
          string oldname, newname;
          INamedModel Model { get; set; }

          ItemRenameCommand(INamedModel model, string oldname, string newname) {
          this.oldname = oldname; this.newname = newname;
          Model = model;
          }

          void Undo() { Model.Name = oldname; }
          void Redo() { Model.Name = newname; }
          }

          class MainForm : Form {
          ...
          void TreeNodeRenamed(object sender, NodeRenameEventArgs e){
          IUndoableCommand renameCommand = new ItemRenameCommand(treeViewModel, e.OldName, e.NewName);
          undoStack.Push(renameCommand);
          }

          Stack<IUndoableCommand> undoStack, redoStack;
          }

          (Remember, pseudocode; I can't remember how you actually hook onto the rename event of a TreeView, and it's not really the main point of the discussion, but it means that won't compile.) INamedModel is just for the Name property, you'd typically have all your view model classes implement something like that in a strongly typed environment. One can have an argument about whether the undo/redo stacks should be in the UI (i.e. the view) or the view-model, taking a MVVM approach to structure. I tend to feel that because it represents user actions, it is part of the view. Then, to undo, you take items off the undo stack and call .Undo() on each of them in turn, pushing them onto the redo stack. And to redo, you take items off the redo stack, move them to the undo stack and call .Redo() on each one. The tricky bit is making sure that everything can be represented by a reversible command. For some things (simplistic example, a Reset or Randomise button) you will have to store most or all of the previous state, but avoid doing that in all cases where it is possible to do so, as storing the whole state for each undo entry is a

          B Offline
          B Offline
          BillWoodruff
          wrote on last edited by
          #4

          Hi Bob, This is a great answer, thanks, and, imho, far more than this as-yet-non-responsive questioner deserves, or can probably "handle." But, I do feel that if the OP wants to implement Undo for just the Text displayed on TreeNodes, that's okay. People new to the game often need to start at a lower level of abstraction, and solving specific problems may, perhaps, lead them, later, to be able to have a "basis" for understanding higher-level abstractions and code strategies. If the OP shows any response, I'll help he or she with a simple example of Undo with the TreeNode text. best, Bill

          "Beauty is in the eye of the beholder, and it may be necessary from time to time to give a stupid or misinformed beholder a black eye." Miss Piggy"

          1 Reply Last reply
          0
          • B BobJanova

            You shouldn't 'implement the Undo Functionality for rename'. You should implement undo as an app-wide thing which maintains a stack of commands across the whole application and knows how to undo them. There's two ways to do undo: either you maintain the state before each operation, or you store each operation as a command which knows how to undo itself. In all but the simplest case you want to do the second way. You need to implement every action within your application as a command, where command means something like:

            interface IUndoableCommand {
            void Undo();
            void Redo();
            }

            In this case, assuming your tree view is bound to some view-model level property, you would hook the NodeRenamed event (whatever it's actually called) - pseudocode:

            class ItemRenameCommand : IUndoableCommand {
            string oldname, newname;
            INamedModel Model { get; set; }

            ItemRenameCommand(INamedModel model, string oldname, string newname) {
            this.oldname = oldname; this.newname = newname;
            Model = model;
            }

            void Undo() { Model.Name = oldname; }
            void Redo() { Model.Name = newname; }
            }

            class MainForm : Form {
            ...
            void TreeNodeRenamed(object sender, NodeRenameEventArgs e){
            IUndoableCommand renameCommand = new ItemRenameCommand(treeViewModel, e.OldName, e.NewName);
            undoStack.Push(renameCommand);
            }

            Stack<IUndoableCommand> undoStack, redoStack;
            }

            (Remember, pseudocode; I can't remember how you actually hook onto the rename event of a TreeView, and it's not really the main point of the discussion, but it means that won't compile.) INamedModel is just for the Name property, you'd typically have all your view model classes implement something like that in a strongly typed environment. One can have an argument about whether the undo/redo stacks should be in the UI (i.e. the view) or the view-model, taking a MVVM approach to structure. I tend to feel that because it represents user actions, it is part of the view. Then, to undo, you take items off the undo stack and call .Undo() on each of them in turn, pushing them onto the redo stack. And to redo, you take items off the redo stack, move them to the undo stack and call .Redo() on each one. The tricky bit is making sure that everything can be represented by a reversible command. For some things (simplistic example, a Reset or Randomise button) you will have to store most or all of the previous state, but avoid doing that in all cases where it is possible to do so, as storing the whole state for each undo entry is a

            N Offline
            N Offline
            Nyanoba
            wrote on last edited by
            #5

            Hi Bob, thanks, Its the one which i needed..

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups