views:

460

answers:

3

We use windows forms and custom user controls and I would like to be able to rotate the panel hosting the userControl in a particular form. I have seen similar functionnalities with WPF but can't use it for the moment. Is it possible to achieve the rotation of a panel and its children using possibly built-in .net methods or GDI+ ? I have seen some pretty cool visual effect with menus that are displayed in game development so I was wondering if it would be possible to create similar effects using winforms.

+1  A: 

You can use rotations in GDI+ by calling the RotateTransform method on a Graphics object.

However, rotating an entire control is not so simple, and will depend heavily on how the control is implemented.
If it's a composite UserControl that has other controls inside of it, you're out of luck.
If it's a sinlge control that paints itself, try inheriting the control, overriding the OnPaint method, and calling RotateTransform on the Graphics object. However, you will probably have trouble with it. In particular, you will probably need to override all of the mouse events and call the base control's events with rotated coordinates.

SLaks
+1  A: 

Rotating a panel and its children in WinForms is not something directly supported and I think it will end up being a buggy headache that could easily suck up lots of time. Its especially painful to think about when you could do this in WPF with zero lines of C# code and only a tiny bit of XAML.

Brian Ensink
A: 

You can get halfway there by calling the DrawToBitmap method on your panel, then rotating the bitmap and displaying it e.g. in a PictureBox:

Bitmap bmp = new Bitmap(panel.Width, panel.Height);
panel.DrawToBitmap(bmp, new Rectangle(Point.Empty, panel.Size));
bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);

PictureBox pbox = new PictureBox();
pbox.Location = panel.Location;
pbox.SizeMode = PictureBoxSizeMode.AutoSize;
pbox.Image = bmp;
Controls.Remove(panel);
Controls.Add(pbox);

Rotation angles other than 90-degree increments are also possible, if you draw the bitmap into another bitmap using GDI:

Bitmap bmp2 = new Bitmap(bmp.Width + 75, bmp.Height + 100);
Graphics g = Graphics.FromImage(bmp2);
g.TranslateTransform(bmp2.Width / 2, bmp2.Height / 2);
g.RotateTransform(-15f);
g.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
g.DrawImageUnscaled(bmp, Point.Empty);
g.Dispose();

The problem of course is that you're only displaying an image of your panel, and not the panel itself, so it's no longer possible to interact with the controls inside. That could probably be done as well, but you would have to mess with window messages, which gets quite a bit more complicated. Depending on your needs you might also be able to get away with handling click and key events on the PictureBox, manipulating the controls in the panel, and then updating the image.

Aaron