0

I have a form that includes a panel with buttons that gets generated by code (so they don't exist on the form at start) and placed on the panel. typically about 10-20 buttons but could possibly get up to about 100.

Now I need the user be able to rotate, change shape and dimensions of the buttons individually, as well move them by mouse (got this part working using the buttons). The Button class don't seem to be the way to go so I started reading about shapes, paint events, pictureboxes and the like but I cant figure out a neat way of doing it.

EDIT Ok, so I have gotten somewhere using the paint event but when I move my test button it flickers a lot. this is my code so far:

public class CustomButton
{
    Panel panel;
    private MyData data;

    private Point mouseClickLocation;
    private bool selected = false;
    private bool moving = false;

    int dX = 0;
    int dY = 0;


    //constructor
    public TableGraphics(MyData newData, Panel newPanel)
    {
        panel = newPanel;
        data = newData;
        panel.Paint += new System.Windows.Forms.PaintEventHandler(this.OnPaintHandler);
        panel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDownHandler);

    }

    //paint eventhandler
    public void OnPaintHandler(object sender, PaintEventArgs e)
    {

        Rectangle rect = new Rectangle(data.ButtonLocation, data.ButtonSize);

        using (Pen pen = new Pen(Color.Red, 5))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }

    //mouse down eventhandler
    public void OnMouseDownHandler(object sender, MouseEventArgs e)
    {
        Point buttonLocation = data.ButtonLocation;
        Size buttonSize = data.ButtonSize;

        //do we hit this object?
        if ((e.X < buttonLocation.X + buttonSize.Width) && (e.X > buttonLocation.X) &&
            (e.Y < buttonLocation.Y + buttonSize.Height) && (e.Y > buttonLocation.Y))
        {
            panel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMouseUpHandler);
            panel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMoveHandler);
            selected = true;
            mouseClickLocation = e.Location;
        }
        else
        {
            //deselect
            selected = false;
        }

    }

    //mouse up eventhandler
    public void OnMouseUpHandler(object sender, MouseEventArgs e)
    {
        if (selected)
        {
            selected = false;
            moving = false;
            panel.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.OnMouseUpHandler);
            panel.MouseMove -= new System.Windows.Forms.MouseEventHandler(this.OnMouseMoveHandler);
        }

    }

    //mouse drag eventhandler
    public void OnMouseMoveHandler(object sender, MouseEventArgs e)
    {
        if(selected && moving)
        {
            data.ButtonLocation = new Point(e.X + dX, e.Y + dY);
            panel.Invalidate();
        }
        else if (selected && !moving)
        {
            dX = e.X - mouseClickLocation.X;
            dY = e.Y - mouseClickLocation.Y;
            int distance = ((dX * dX) + (dY * dY));

            if(distance > 15)
            {
                dX = data.ButtonLocation.X - e.X;
                dY = data.ButtonLocation.Y - e.Y;
                moving = true;
            }
        }
    }
}

The CustomButton is created from a form and fed a data class that is stored elsewhere and a reference to the panel on the form, one time for each data object that exist (so far just 1 for testing purposes)

Taxen0
  • 55
  • 8
  • Welcome to SO. You should try at least something first, then show us your code and ask for help using [MCVE]. – Pavel Pája Halbich Jul 26 '17 at 11:35
  • Thank you, I have tried a few different approaches but as I'm not sure if I'm even on the right track I did not post them to avoid confusion. I will try and clean up one of them and add it though! – Taxen0 Jul 26 '17 at 11:42
  • You can't rotate controls, really. You can [fake](https://stackoverflow.com/questions/5130008/is-it-possible-to-rotate-a-button-control-in-winforms/28617171?s=1|1.1485#28617171) it it, but only in 90 degrees steps. - you can easily drag them around with the mouse and even resize them. The more shapes you want the better [drawing](https://stackoverflow.com/questions/23954653/winforms-draw-then-move-rectangle/23957767?s=1|3.8215#23957767) them will be. You can define a class for this with a Paint event and all sorts of properties.. - I would not recommend drag&drop, though. Stick to MouseXXX! – TaW Jul 26 '17 at 11:51
  • One weird alternative btw is using a Chart and annotations; the can be set to be moveable, and sizeable, will scale with the chart and a few more things.. – TaW Jul 26 '17 at 11:59
  • @TaW This is what my research concluded as well, but I haven't really used drawing and paint events before and is unsure how to handle the mouse input – Taxen0 Jul 26 '17 at 12:12
  • In addition to the links [this post](https://stackoverflow.com/questions/32919918/how-to-draw-line-and-select-it-in-panel/32920894?s=1|3.0563#32920894) may be of interest. - For better advice do give more info on the way the use chnages shape and rotates. Also aout text if any is needed.. – TaW Jul 26 '17 at 12:22
  • Thank you again, got the hit detection working nicely. But now the shape flicker when I move it. Updated the question with my code – Taxen0 Jul 27 '17 at 12:43