Вращение панели.NET в Windows Forms

Мы используем Windows Forms и пользовательские элементы управления, и я хотел бы иметь возможность вращать панель с пользовательским контролем в определенной форме. Я видел подобные функциональные возможности с WPF, но пока не могу его использовать. Можно ли добиться поворота панели и ее дочерних элементов с помощью, возможно, встроенных методов.NET или GDI +?

Я видел довольно крутой визуальный эффект с меню, отображаемым при разработке игры, поэтому мне было интересно, можно ли создать подобные эффекты с помощью Windows Forms.

3 ответа

Решение

Вращение панели и ее дочерних элементов в Windows Forms не поддерживается напрямую, и я думаю, что в конечном итоге это будет глючная головная боль, которая может легко поглотить много времени. Особенно больно думать о том, когда вы могли бы сделать это в WPF с нулевыми строками кода на C# и только с небольшим количеством XAML.

Вы можете использовать вращение в GDI+, вызвав метод RotateTransform для Graphics объект.

Однако вращение всего элемента управления не так просто, и будет сильно зависеть от того, как этот элемент управления реализован.
Если это составной UserControl, в котором есть другие элементы управления, вам не повезло.
Если это элемент управления sinlge, который рисует сам, попробуйте наследовать элемент управления, переопределяя OnPaint метод и вызов RotateTransform на графическом объекте. Тем не менее, вы, вероятно, будете иметь проблемы с этим. В частности, вам, вероятно, потребуется переопределить все события мыши и вызвать события базового элемента управления с повернутыми координатами.

Вы можете достичь этого на полпути, вызвав метод DrawToBitmap на своей панели, затем вращая растровое изображение и отображая его, например, в 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);

Углы поворота, отличные от приращений в 90 градусов, также возможны, если вы рисуете растровое изображение в другом растровом изображении, используя 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();

Проблема, конечно, заключается в том, что вы отображаете только изображение своей панели, а не саму панель, поэтому больше невозможно взаимодействовать с элементами управления внутри. Скорее всего, это тоже можно сделать, но вам придется возиться с оконными сообщениями, что немного сложнее. В зависимости от ваших потребностей вы также можете избежать обработки событий щелчка и нажатия клавиш в PictureBox, манипулирования элементами управления на панели и последующего обновления изображения.

Другие вопросы по тегам