简体   繁体   English

在 Windows 窗体中旋转 .NET 面板

[英]Rotating a .NET panel in Windows Forms

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.我们使用Windows 窗体和自定义用户控件,我希望能够以特定形式旋转托管 userControl 的面板。 I have seen similar functionnalities with WPF , but I can't use it for the moment.我已经看到WPF 的类似功能,但我暂时无法使用它。 Is it possible to achieve the rotation of a panel and its children using possibly built-in .NET methods or GDI+ ?是否可以使用可能的内置 .NET 方法或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 Windows Forms.我在游戏开发中看到了一些非常酷的菜单视觉效果,所以我想知道是否可以使用 Windows 窗体创建类似的效果。

You can use rotations in GDI+ by calling the RotateTransform method on a Graphics object.您可以通过调用Graphics对象上的RotateTransform方法在 GDI+ 中使用旋转。

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.如果它是一个内部包含其他控件的复合 UserControl,那么您就不走运了。
If it's a sinlge control that paints itself, try inheriting the control, overriding the OnPaint method, and calling RotateTransform on the Graphics object.如果它是一个自行绘制的单一控件,请尝试继承该控件,覆盖OnPaint方法,并在 Graphics 对象上调用RotateTransform 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.特别是,您可能需要覆盖所有鼠标事件并使用旋转坐标调用基本控件的事件。

Rotating a panel and its children in Windows Forms is not something directly supported, and I think it will end up being a buggy headache that could easily suck up lots of time.在 Windows 窗体中旋转面板及其子项不是直接支持的,我认为它最终会成为一个容易占用大量时间的问题。 It's 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 .考虑何时可以在WPF 中使用零行 C# 代码和仅少量XAML执行此操作特别痛苦。

You can get halfway there by calling the DrawToBitmap method on your panel, then rotating the bitmap and displaying it eg in a PictureBox:您可以通过在面板上调用 DrawToBitmap 方法,然后旋转位图并在例如图片框中显示它来获得一半效果:

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

var pictureBox = new PictureBox();

pictureBox.Location = panel.Location;
pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox.Image = bitmap;

Controls.Remove(panel);
Controls.Add(pictureBox);

Rotation angles other than 90-degree increments are also possible, if you draw the bitmap into another bitmap using GDI:如果使用 GDI 将位图绘制到另一个位图中,则也可以使用 90 度增量以外的旋转角度:

var bitmap2  = new Bitmap(bmp.Width + 75, bmp.Height + 100);
var graphics = Graphics.FromImage(bmp2);

graphics.TranslateTransform(bitmap2.Width / 2, bitmap2.Height / 2);
graphics.RotateTransform(-15f);
graphics.TranslateTransform(-bitmap.Width / 2, -bitmap.Height / 2);
graphics.DrawImageUnscaled(bitmap, Point.Empty);
graphics.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.根据您的需要,您可能还可以处理 PictureBox 上的单击和键事件,操作面板中的控件,然后更新图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM