2

TL;DR;
How can I add copy-paste capability to a complex, multiple values property that will enable me to copy the property value from one user control and paste it to another at design time?

The long story

I have created a user control (StylableControl) that has a complex property called Style.

This property contains an instance of a class called StylableControlStyles, that contains multiple instances of a class called Style, where each one holds values such as BackColor, ForeColor, Image, Gradient (another class I've created) etc'.

I've also created a custom control designer to allow editing style property for the user control. It shows a form where each style class in the style property can be edited easily.

Now I want to provide the users of this control an easy way to copy the entire content of the Style property from one instance of the user control to another instance, at design time.

I could, of course, override the ToString() method of the StylableControlStyles object to create a string representation that will encapsulate all the data saved in this object, but that would create a hugh string and of course would need a lot of work parsing it in the class converter (currenty I'm just using an ExpandableObjectConverter).
I would like to avoid that if possible.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • Are you maybe simply looking for a way to deep clone or deep copy an object hierarchy? If so, there are already [several answers](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net-c-specifically) [here on SO](http://stackoverflow.com/questions/78536/deep-cloning-objects) – jcb Feb 28 '17 at 11:20
  • @jcb Actually, the colning part is alreay written, that's not my problem. I'm looking for a way to provide design-time support for copy - paste values between controls on a form. Something like a smart tag command that will enable the user to choose another instance of the user control and copy it's style into the current instance's style. – Zohar Peled Feb 28 '17 at 11:23
  • @ZoharPeled, if you already have custom control designer form, add Copy Style and Apply Copied Style buttons there, for example. Copied style can be stored in some buffer (maybe even Clipboard. if it is human-readable format, users will be able to insert copied value into .designer.cs file directly) – ASh Feb 28 '17 at 13:41
  • @ZoharPeled, alternatively, do you know how DataGridView add some quick access functions in designer (see [this screenshot](https://i.stack.imgur.com/Tmbc6.png)). It is possible to add similar actions (Copy Style..., Apply Style...) to a custom user control – ASh Feb 28 '17 at 13:43
  • @Ash That's actually a very good idea. I'll try it. If you could post it as an answer I'll be happy to upvote and accept it if I'll be able to make it work. – Zohar Peled Feb 28 '17 at 13:44
  • @ZoharPeled, I'm sure SO has a good QA which can be used as a duplicate (e.g. [this one](http://stackoverflow.com/questions/39024850/custom-control-clickable-link-in-properties-box)) – ASh Feb 28 '17 at 13:53
  • @Ash Brilliently simple. I should have thought about it myself. I've used a static variable in the control designer to serve as a buffer. works like a charm, thanks. Sure you don't want a free 25 rep. points bonus? – Zohar Peled Feb 28 '17 at 14:47
  • If `StylableControlStyles` is marked as `Serializable` (and it's indeed serializable), it *should* work as-is – Jcl Mar 01 '17 at 09:52

1 Answers1

0

Following Ash's advice in the comments I've used a DesignerVerb to copy and paste the Style to and from a private static member of type Style of the control designer.

So in my control designer class I have:

private static ZControlStyle _CopiedStyle;

And have added these designer verbs:

_Verbs.Add(new DesignerVerb("Copy Styles", CopyStyle));
_Verbs.Add(new DesignerVerb("Paste Styles", PasteStyle));

And the methods for copy ans paste:

private void PasteStyle(object sender, EventArgs e)
{
    if (_CopiedStyle != null)
    {
        var toggleButton = Control as ZToggleButton;
        if (toggleButton != null)
        {
            toggleButton.Style.FromStyle(_CopiedStyle);
        }
        else
        {
            (Control as ZControl).Style.FromStyle(_CopiedStyle);
        }

    }
}

private void CopyStyle(object sender, EventArgs e)
{
    var toggleButton = Control as ZToggleButton;
    if (toggleButton != null)
    {
        _CopiedStyle = toggleButton.Style;
    }
    else
    {
        _CopiedStyle = (Control as ZControl)?.Style;
    }
}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121