Suggest a cut/copy/paste strategy for columns with different cell types?

Posted by: jhoover on 8 September 2017, 1:38 pm EST

  • Posted 8 September 2017, 1:38 pm EST

    I have a spread with cell types that vary by row.
    For example, the first row is text, the next several rows are numeric, there are three rows of combos (that display text with numeric values "behind" them), more numeric rows, and so on.


    The behavior I'd like is:
     - Ctrl-c, ctrl-v and ctrl-x should work whether or not cell is in edit mode
     - A context menu should allow cut/copy/paste/delete whether or not cell is in edit mode
     - Cut should not clear the combos
     - Paste should honor the cell types so that if I copy a range of cells that contain numbers and paste them into a range that contains combos, the combos don't change.


    If possible, I'd like to acheive this without writing lots of code to search through the clipboard data and the destination cells and decide on a cell-by-cell basis what to do.


    Can someone suggest an approach to take that makes the most use of built-in Spread features?


    Thanks,


    Jeff

  • Replied 8 September 2017, 1:38 pm EST

    Hi Scott,
    I'm getting back to this issue. I've clarified how I'd like things to work:

     
























     



    Number



    Text



    Combo



    Edit Mode



    Ctrl-C/X copies/cuts selection, Ctrl-V conditionally [does
    nothing] or [overwrites selection] depending on whether clipboard contents
    are numeric



    Ctrl-C/X copies/cuts selection, Ctrl-V overwrites selection with
    clipboard contents



    Ctrl-C/X copies/copies selection item, Ctrl-V conditionally
    [selects item] or [does nothing] depending on whether clipboard contents
    match an item



    Not Edit Mode



    Ctrl-C/X copies/cuts entire cell contents, Ctrl-V conditionally
    [does nothing] or [overwrites entire cell contents] depending on whether
    clipboard contents are numeric



    Ctrl-C/X copies/cuts entire cell contents,  Ctrl-V overwrites
    entire cell contents with clipboard contents



    Ctrl-C/X copies/copies entire cell contents, Ctrl-V
    conditionally [selects item] or [does nothing] depending on whether clipboard
    contents match an item



    Locked



    NA



    Ctrl-C/X copies/copies selection, Ctrl-V conditionally [does
    nothing] or [overwrites entire cell contents] depending on clipboard contents



    NA


     More notes:

      Should support undo

      If the number of selected cells does not equal the number of cells on the clipboard, I think I'd like to paste the entire clipboard starting at the upper left corner of the selected area.

      If the destination contains cells of differing types from those of the copied cells, the behavior for each destination cell should abide by the rules in the table.


    Can you suggest a strategy for me? (And if you can write code snips in C#, that would be really great. If not, VB's OK)

     Thanks,

    Jeff Hoover

  • Replied 8 September 2017, 1:38 pm EST

    Jeff,


    For the first two items, you need to decide how you want to copy, paste, etc when you are in editmode. You can create an entry in the ActionMap that catches this keystroke and turns off editmode (EditMode = False) before processing the clipboard action. Here is code to set the InputMap on the Spread to take care of your 3rd and 4th question.


    Dim im As FarPoint.Win.Spread.InputMap


    im = FpSpread1.GetInputMap(FarPoint.Win.Spread.InputMapMode.WhenFocused)


    im.Put(New FarPoint.Win.Spread.Keystroke(Keys.V, Keys.Control), FarPoint.Win.Spread.SpreadActions.ClipboardPasteValues)


    im.Put(New FarPoint.Win.Spread.Keystroke(Keys.X, Keys.Control), FarPoint.Win.Spread.SpreadActions.ClipboardCutDataOnly)

  • Replied 8 September 2017, 1:38 pm EST

    Jeff,


    Both of these functionalities happen by default. You would need to remove my second set of InputMaps from the last code and then the Spread should act the way you want it to.

  • Replied 8 September 2017, 1:38 pm EST

    Jeff,


    Here is some code to set up the Spread to copy, cut and paste as you are expecting. This code does not setup the Undo support. You can search the forums for the UndoAction class to create undo support the way you want. Also, Spread does not support pasting to blocks larger than the copy block selection and filling the extra cells with repeated data. This would require a lot of code to determine how youl would want to repeat the data.


    private void Form1_Load(object sender, EventArgs e)


    {


    //Setup Spread to Cut DataOnly and Paste only values when not in editmode.


    FarPoint.Win.Spread.InputMap im = new FarPoint.Win.Spread.InputMap();


    im = fpSpread1.GetInputMap(FarPoint.Win.Spread.InputMapMode.WhenFocused);


    im.Put(new FarPoint.Win.Spread.Keystroke(Keys.V, Keys.Control), FarPoint.Win.Spread.SpreadActions.ClipboardPasteValues);


    im.Put(new FarPoint.Win.Spread.Keystroke(Keys.X, Keys.Control), FarPoint.Win.Spread.SpreadActions.ClipboardCutDataOnly);


    //Setup copy entire cell and cut data only from entire cell when Spread is in editmode.


    FarPoint.Win.Spread.InputMap im2 = new FarPoint.Win.Spread.InputMap();


    FarPoint.Win.Spread.ActionMap am2 = new FarPoint.Win.Spread.ActionMap();


    im2 = fpSpread1.GetInputMap(FarPoint.Win.Spread.InputMapMode.WhenAncestorOfFocused);


    am2 = fpSpread1.GetActionMap();


    am2.Put("CopyEditMode", new CopyEditMode());


    am2.Put("CutEditMode", new CutEditMode());


    im2.Put(new FarPoint.Win.Spread.Keystroke(Keys.C, Keys.Control), "CopyEditMode");


    im2.Put(new FarPoint.Win.Spread.Keystroke(Keys.X, Keys.Control), "CutEditMode");


    }


    }


    public class CopyEditMode : FarPoint.Win.Spread.Action


    {


    public override void PerformAction(object sender)


    {


    FarPoint.Win.Spread.SpreadView sv = (FarPoint.Win.Spread.SpreadView)sender;


    sv.StopCellEditing();


    sv.Sheets[0].ClipboardCopy();


    }


    }


    public class CutEditMode : FarPoint.Win.Spread.Action


    {


    public override void PerformAction(object sender)


    {


    FarPoint.Win.Spread.SpreadView sv = (FarPoint.Win.Spread.SpreadView)sender;


    sv.StopCellEditing();


    sv.Sheets[0].ClipboardCopy();


    sv.Sheets[0].ClearRange(sv.Sheets[0].ActiveRowIndex, sv.Sheets[0].ActiveColumnIndex, 1, 1, true);


    }


    }

  • Replied 8 September 2017, 1:38 pm EST

    Thanks Scott.I have some questions about your suggestion.

    Is New the VB.Net "magic constructor"  (mentioned here)?

     Would I implement it in C# like this?

     

            protected CustomCellType1(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
                : base(info, context)
            {
                // Is *this* the method called during the paste?
            }

     I just tried this and neither method hits during copy. During paste, GetObjectData() hits3 times then the constructor above hits once.

    What am I doing wrong?

     I attached a sample project.

     

    Also, does it matter if my celltype derives from NumericCellType?

    Thanks again,

    Jeff


    2009/02/CustomCellTest.zip
  • Replied 8 September 2017, 1:38 pm EST

    Scott,

    Thanks for the response. A few clarifications:

    I'm not interested in any repeat. What I imagined when pasting to blocks larger than the copy block selection is something like this: Say I select 4 consecutive columns in the same row and copy those 4 cells. Then I go somewhere else and select 5 consecutive columns in three neighboring rows and paste into them. I imagine that the contents from the 4 cells will go into the 4 upper-left cells of the 150 cell selection and the others will be unchanged. (See attached .jpg)

     

    Also I have not looked closely at your code yet, but I see the comment:

    //Setup copy entire cell and cut data only from entire cell when Spread is in editmode.

    What I was imagining is that say I have a cell that contains ABC123XYZ and I select 123 and copy. Rather than the clipboard containing ABC123XYZ, I'd want it to contain 123

     

    And I'll investigate UndoAction.

     

    Jeff


    2009/02/farpoint_paste_larger.JPG
  • Replied 8 September 2017, 1:38 pm EST

    Jeff,


    Here is the information you are looking for with custom celltypes.


    Public Class myCellType


    Inherits FarPoint.Win.Spread.CellType.GeneralCellType


    Public Overrides Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)


    'This is the method called during the copy


    MyBase.GetObjectData(info, context)


    End Sub


    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)


    'This is the call that happens on the paste.


    End Sub


    End Class

  • Replied 8 September 2017, 1:38 pm EST

    Thanks Scott.

     It turns out things are more complicated than I thought because we use a CustomCellType. I'll search in the forum for information on custom copy/paste handlers for CustomCellTypes.

     

    Jeff

  • Replied 8 September 2017, 1:38 pm EST

    OK, so how do I use this to make custom copy/paste behavior?

    I can loop through the SerializationInfo's SerializationInfoEnumerator, but that seems to get me everything about the cell except its content.

     I'm sure I'm missing something.

  • Replied 8 September 2017, 1:38 pm EST

    If you want to make the FpSpread use your custom paste action instead of the default one, you need to replace the entry in the ActionMap for SpreadActions.ClipboardPaste.  Undo actions that are referenced in the action maps must be stateless and use the sender argument passed into the PerformUndoAction and Undo method to get a reference to the SpreadView object:

    SpreadView spreadView = sender as SpreadView; 

    From the SpreadView, you can get to the FpSpread using the Owner property, and you can get to the SheetView using the GetSheetView method.  The undo actions in the action map are copied using UndoAction.Clone before being passed to the UndoManager.PerformUndoAction method.  That way the undo state is saved into the copy of the action rather than the one in the action map, and each copy can have independent undo state.

    You can also explicitly call UndoManager.PerformUndoAction in your code to perform the action.

  • Replied 8 September 2017, 1:38 pm EST

    Once I subclass ClipboardPasteUndoAction and override PerformUndoAction(), what would I hook my new UndoAction to?
  • Replied 8 September 2017, 1:38 pm EST

    Hi,

    The SerializationInfo for your custom cell type will contain only what you (and any base classes) put into it in the GetObjectData implementation.  That would not be the place to put code for customizing the paste behavior as you have described.

    You will need to create a custom undo action class to implement the paste behavior that you want.  You can inherit from ClipboardPasteUndoAction and override the PerformUndoAction method to make your action do what you want (i.e. get the clipboard data, check the target range for particular contents, etc.).  The SaveUndoState and Undo methods probably do not need to be overridden.

    You can use Reflector to look at how the ClipboardPasteUndoAction class works to give you a better idea of how to implement a custom action.

     

  • Replied 8 September 2017, 1:38 pm EST

    Jeff,


    What you are seeing is correct behavior. During the ClipboardCopy method, the serialization does not happen. This happens during the Paste. With AllowUndo turned on, this will be called several times. First for the copying of the data from the source, then for the copy of the data in the target cells (so it can be put back during an Undo). I am not sure what the third time is for.


    Then the paste happens in the target cell which calls the "magic" constructor. This so called "magic" constructor is the constructor of the class that takes a SerializationInfo and StreamingContext from the deserialization of the binary data that was stored during the copy.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels