Copying/Cloning a control

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?Sm9uIEVsbGlz?=

    #1

    Copying/Cloning a control

    Hi All,

    I want to implement an 'generic' undo by placing a copy of a control in a
    stack using System.Collecti ons.Generic.Sta ck. Basically this way I don't need
    to know if a user has edited text in tree, added or deleted a node etc,
    added items to a list box etc etc. I just push the control onto the stack
    when they change it (regardless of control type) and Pop if back if they undo.

    My problem is how to a get a copy of the control? Obviosuly if I push the
    control onto the stack, I get a reference to the original so every entry on
    the stack is always the same, so I need to make a copy of the control that is
    independant of the original.

    Is there an *easy* way to do this - I've found a few examples, but they seem
    dependant on knowing exactly what type of control it is, and wind through all
    the properties etc, I was hoping for something more generic.

    I am using VB.Net 2005.

    Thanks in advance!


    --
    Jon
  • Robin Tucker

    #2
    Re: Copying/Cloning a control

    Hi Jon,

    I don't think this idea is very good to be honest. There is a lot of
    plumbing associated with a control that is just superfluous in an undo-redo
    context - especially in a tree view where you are only interested in what
    happened to the last node (i.e. subtree).

    It's easy to create a structure for undo-redo where you do know precisely
    what action occurred. Create a simple class hierarchy with overridable
    method "Undo" and "Redo" - it's also useful to add in "CanUndo" and
    "CanRedo", along with a "Size" and "Label" property (so you can know how
    much space your undo-redo stack is taking up and can possibly tell the user
    what the undo/redo action will do). Keep state information in the instance.
    When the user deletes a node, you add a "NodeDelete d" class instance onto
    your stack. When he inserts a node, you add a "NodeInsert ed" class
    instance. Both of these are derived from your undo-redo base class.

    Thestructure can be used in other contexts. For example if you are deleting
    from a listview, where that node is also present in the tree, you still only
    need the 1 undo-redo instance.



    Robin


    Comment

    • =?Utf-8?B?cnViZW4=?=

      #3
      RE: Copying/Cloning a control

      Just trying to help in the control cloning because I recently need it.
      I developed the following function but at the end I didn't use it because I
      changed my mind about cloning.

      Private Function CloneControl(By Val Ctrl As Control, ByVal Parent As
      Object) As Control
      Try
      Dim CtrlType As Type = Ctrl.GetType()
      Dim CtrlObject As Object = Activator.Creat eInstance(CtrlT ype)
      Dim CtrlNew As Control = CtrlObject

      Dim pdcCtrl As
      System.Componen tModel.Property DescriptorColle ction =
      System.Componen tModel.TypeDesc riptor.GetPrope rties(Ctrl)
      Dim pdcCtrlNew As
      System.Componen tModel.Property DescriptorColle ction =
      System.Componen tModel.TypeDesc riptor.GetPrope rties(CtrlNew)
      For i As Integer = 0 To pdcCtrl.Count - 1
      If pdcCtrl(i).Name = "Parent" Then
      CtrlNew.Parent = Parent

      ElseIf pdcCtrl(i).Name = "Controls" Then
      If Not Ctrl.Controls Is Nothing Then
      For Each CtrlChild As Control In Ctrl.Controls
      CtrlNew.Control s.Add(CloneCont rol(CtrlChild,
      CtrlNew))
      Next
      End If

      Else
      pdcCtrlNew(i).S etValue(CtrlNew , pdcCtrl(i).GetV alue(Ctrl))
      End If
      Next

      Return CtrlNew

      Catch ex As Exception
      Return Nothing
      End Try
      End Function

      ex. calling the function:
      Dim tb as TextBox
      tb = CloneControl(Te xtBox1, Nothing)

      Hope this helps!

      "Jon Ellis" wrote:
      Hi All,
      >
      I want to implement an 'generic' undo by placing a copy of a control in a
      stack using System.Collecti ons.Generic.Sta ck. Basically this way I don't need
      to know if a user has edited text in tree, added or deleted a node etc,
      added items to a list box etc etc. I just push the control onto the stack
      when they change it (regardless of control type) and Pop if back if they undo.
      >
      My problem is how to a get a copy of the control? Obviosuly if I push the
      control onto the stack, I get a reference to the original so every entry on
      the stack is always the same, so I need to make a copy of the control that is
      independant of the original.
      >
      Is there an *easy* way to do this - I've found a few examples, but they seem
      dependant on knowing exactly what type of control it is, and wind through all
      the properties etc, I was hoping for something more generic.
      >
      I am using VB.Net 2005.
      >
      Thanks in advance!
      >
      >
      --
      Jon

      Comment

      • =?Utf-8?B?Sm9uIEVsbGlz?=

        #4
        RE: Copying/Cloning a control

        Ruben,

        Thanks for the response, but the following line just generates a an error (A
        first chance exception of type 'System.Compone ntModel.Win32Ex ception'
        occurred in System.dll) repeatedly -

        pdcCtrlNew(i).S etValue(CtrlNew , pdcCtrl(i).GetV alue(Ctrl))

        Think I'm going give up on the idea; just thought it would be a neat way of
        implementing do/undo for any control.

        --
        Jon


        "ruben" wrote:
        Just trying to help in the control cloning because I recently need it.
        I developed the following function but at the end I didn't use it because I
        changed my mind about cloning.
        >
        Private Function CloneControl(By Val Ctrl As Control, ByVal Parent As
        Object) As Control
        Try
        Dim CtrlType As Type = Ctrl.GetType()
        Dim CtrlObject As Object = Activator.Creat eInstance(CtrlT ype)
        Dim CtrlNew As Control = CtrlObject
        >
        Dim pdcCtrl As
        System.Componen tModel.Property DescriptorColle ction =
        System.Componen tModel.TypeDesc riptor.GetPrope rties(Ctrl)
        Dim pdcCtrlNew As
        System.Componen tModel.Property DescriptorColle ction =
        System.Componen tModel.TypeDesc riptor.GetPrope rties(CtrlNew)
        For i As Integer = 0 To pdcCtrl.Count - 1
        If pdcCtrl(i).Name = "Parent" Then
        CtrlNew.Parent = Parent
        >
        ElseIf pdcCtrl(i).Name = "Controls" Then
        If Not Ctrl.Controls Is Nothing Then
        For Each CtrlChild As Control In Ctrl.Controls
        CtrlNew.Control s.Add(CloneCont rol(CtrlChild,
        CtrlNew))
        Next
        End If
        >
        Else
        pdcCtrlNew(i).S etValue(CtrlNew , pdcCtrl(i).GetV alue(Ctrl))
        End If
        Next
        >
        Return CtrlNew
        >
        Catch ex As Exception
        Return Nothing
        End Try
        End Function
        >
        ex. calling the function:
        Dim tb as TextBox
        tb = CloneControl(Te xtBox1, Nothing)
        >
        Hope this helps!
        >
        "Jon Ellis" wrote:
        >
        Hi All,

        I want to implement an 'generic' undo by placing a copy of a control in a
        stack using System.Collecti ons.Generic.Sta ck. Basically this way I don't need
        to know if a user has edited text in tree, added or deleted a node etc,
        added items to a list box etc etc. I just push the control onto the stack
        when they change it (regardless of control type) and Pop if back if they undo.

        My problem is how to a get a copy of the control? Obviosuly if I push the
        control onto the stack, I get a reference to the original so every entry on
        the stack is always the same, so I need to make a copy of the control that is
        independant of the original.

        Is there an *easy* way to do this - I've found a few examples, but they seem
        dependant on knowing exactly what type of control it is, and wind through all
        the properties etc, I was hoping for something more generic.

        I am using VB.Net 2005.

        Thanks in advance!


        --
        Jon

        Comment

        • Cor Ligthert [MVP]

          #5
          Re: Copying/Cloning a control

          Jon,

          Like Robin I don't think it is a good idea, however the only way I know how
          to do it is serializing and deserializing.



          Cor


          "Jon Ellis" <JonEllis@discu ssions.microsof t.comschreef in bericht
          news:FB150EBE-4A7B-4624-B1DE-019E6E8030C0@mi crosoft.com...
          Hi All,
          >
          I want to implement an 'generic' undo by placing a copy of a control in a
          stack using System.Collecti ons.Generic.Sta ck. Basically this way I don't
          need
          to know if a user has edited text in tree, added or deleted a node etc,
          added items to a list box etc etc. I just push the control onto the stack
          when they change it (regardless of control type) and Pop if back if they
          undo.
          >
          My problem is how to a get a copy of the control? Obviosuly if I push the
          control onto the stack, I get a reference to the original so every entry
          on
          the stack is always the same, so I need to make a copy of the control that
          is
          independant of the original.
          >
          Is there an *easy* way to do this - I've found a few examples, but they
          seem
          dependant on knowing exactly what type of control it is, and wind through
          all
          the properties etc, I was hoping for something more generic.
          >
          I am using VB.Net 2005.
          >
          Thanks in advance!
          >
          >
          --
          Jon

          Comment

          Working...