如何在wpf中旋转窗口? [英] How to spin window in wpf?

查看:57
本文介绍了如何在wpf中旋转窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿伙计们,

我在Window.Loaded事件中在wpf中旋转一个窗口的效果之后几天我一直在搜索谷歌。

当我说旋转时,它意味着我希望窗口显示为在Y轴上以特定的速度旋转。

有什么建议吗?谢天谢地!



我尝试过:



.. .................................................. .................

Hey guys,
I've been searching google for days after an effect that will spin a window in wpf on the Window.Loaded event.
When i'm saying spining, its meaning that i want the window to show as it spin on its Y axis with a specific speed.
any advice? thank a head!

What I have tried:

.....................................................................

推荐答案

没有像旋转窗户那样 ,但你可以相对容易地旋转一些内容。如果这个内容模仿了标准窗口的外观,你可以创建一个旋转窗口的印象。



这是个主意,但是如何实现呢? br />


问题至少包括两个部分,如何以一定角度显示伪窗口,以及如何通过随时间改变此角度来为该视图设置动画。您可以使用两种方法,2D和3D。使用3D,您可以使用形状为长方体的WPF 3D模型,一侧有窗口。 (请参阅三维图形概述 [ ^ ]。)不会很难显示它在一个窗口的背景上,但在空中显示它会更难。我会尝试使用透明背景。



但是使用2D方法,您可以非常轻松地实现与当前伪完全匹配的非矩形形状的背景窗口 - 窗口对象。您可以允许透明度并使此窗口的背景透明。



当然,首先你需要摆脱您的真实背景窗口的所有非客户区域,这是通过使用特殊窗口样式实现的,

Window.WindowStyle Property( System.Windows) [ ^ ],

https://msdn.microsoft.com/en-us/library/system.windows.windowstyle%28v=vs.110%29.aspx [< a href =https://msdn.microsoft.com/en-us/library/system.windows.windowstyle%28v=vs.110%29.aspxtarget =_ blanktitle =New Window> ^ ]。

此外,删除窗口的边框(边框样式)。



要以某个角度显示矩形UI元素,让我假设你不想在空间透视图中显示它。奇怪的是,这不是标准WPF转换支持的转换(而不是 System.Drawing 转换)。这种变换不是仿射(这听起来有点令人惊讶)并且无法创建,但它很棘手;你必须自己做所有事情,直到所有插值问题的像素级别。但如果您同意使用简单的平行投影限制视图,这也可以创建公平的旋转印象,您可以使用变换。



要转换图像,可以使用

转换类(System.Windows.Media) [ ^ ],

转换概述 [ ^ ]。



X中需要显示旋转的变换是缩放变换方向(如果围绕垂直轴旋转): ScaleTransform类(System.Windows.Media) [ ^ ]。



现在,动画。首先,忘记Window.Loaded事件,永远不要记住它。我现在甚至不想讨论它。您只需要始终保持视图动画,或者在某个预定义的时间段内保持视图动画。现在,由于两个因素,您无法使用标准WPF动画。这些因素是:你真的想要表现出均匀的转速,你的变换因子应该是时间的正弦函数,因为角度的变化是线性函数;第二个因素是:您必须在旋转时重新计算和调整区域。



因此,您必须从头开始为旋转设置动画。这是如何:创建一个单独的线程并计算每个旋转阶段的所有几何。然后,在一个非常短的周期中,你必须计算当下的实际时间(使用 System.Diagnostics.Stopwatch Stopwatch Class(System.Diagnostics) [ ^ ])。在每个阶段,您必须通知渲染子系统重新渲染窗口。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。







你不应该将 ScaleTransform 的不同值分配给循环中 UIElement.RenderTransform ;这是不可能的。相反,只做一次(一个正常的地方,以及创建一个线程,在重写 OnContentRendered ),然后,在线程循环中,更改比例因子 Transform.ScaleX



您需要传递 Dispatcher <的实例/ code>和 ScaleTransform 到一个线程。我根据我在这里提出的 ThreadWrapper 解释了一个很好的方法:如何将ref参数传递给线程 [ ^ ]。



[结束编辑#1]



你会在我过去的答案中找到它的工作原理和代码示例的详细说明:

< a href =http://www.codeproject.com/Questions/159098/Control-Invoke-vs-Control-BeginInvoke.aspx> Control.Invoke()与Control.BeginInvoke(),

Treeview扫描仪和MD5的问题



另请参阅有关线程的更多参考资料:

关于mai的.NET活动n线程

如何在vb.net中的另一个线程上运行keydown事件

在启用禁用+多线程后控制事件未触发



如果你做得很好,你的节目可能会给人留下深刻印象。



有人可能会给你其他解决方案或提供更多细节比方说,3D模型方法......







在我的新内容中详细回答简短(提示&技巧) 如何旋转WPF窗口?



本文仅涉及更有趣的2D方法,其中伪旋转的伪窗口产生了旋转印象,我认为这是令人愉快的。 WPF 3D API方法需要付出更多的努力,同时会更加轻松......



[END EDIT#2]



-SA
There is no such thing as spinning a window, but you can relatively easily spin some content. And if this content mimics the appearance of a standard window, you can create an impression of a spinning window.

That was the idea, but how to achieve that?

The problem consists of at least two parts, how to show your pseudo-window at an angle, and how animate this view by changing this angle with time. You can use two approaches, 2D and 3D. With 3D, you can use WPF 3D model shaped as a rectangular parallelepiped with a window on one side. (Please see 3-D Graphics Overview[^].) It will be not to hard to show it on a background of a window, but showing it "in the air" would be much harder. I would try to just use a transparent background.

But with 2D approach, you can pretty easily achieve a non-rectangular shape of a background window perfectly matching your current pseudo-window object. You can allow transparency and make this window's Background transparent.

Of course, first you would need to get rid of all the non-client areas of your "real" background window, which is achieved by using the special window style, None:
Window.WindowStyle Property (System.Windows)[^],
https://msdn.microsoft.com/en-us/library/system.windows.windowstyle%28v=vs.110%29.aspx[^].
Also, remove the window's borders (border style).

To show the rectangular UI element at an angle, let me assume that you don't want to show it in space perspective. Oddly enough, this is not a transform supported by standard WPF transforms (and not by System.Drawing transforms). Such transform is not affine (which also sounds a bit surprising) and cannot be created, but it's tricky enough; you would have to do all yourself, up to the pixel level with all the interpolation problems. But if you agree to limit the view with a simple parallel projection, which can also create fair rotation impression, you can use the transform.

To transform your image, you can use
Transform Class (System.Windows.Media)[^],
Transforms Overview[^].

The transform you need to show rotation is scale transform in X direction (if you "rotate" around the vertical axes): ScaleTransform Class (System.Windows.Media)[^].

Now, animation. First of all, forget "Window.Loaded event" and never remember it. I don't even want to discuss it now. You just have to keep the view animated all the time, or during some predefined period of time. Now, due to two factors, you cannot use standard WPF animation. These factors are: you really want to show uniform rotation speed, your transform factor should be a sinusoidal function of time, because the change of angle is a linear function; the second factor is: you have to recalculate and adjust the region as you rotate.

So, you have to animate the rotation from scratch. This is how: create a separate thread and calculate all the geometry for every phase of rotation. Then, in a pretty short cycle, you have to calculate the real time in the moment (use System.Diagnostics.Stopwatch, Stopwatch Class (System.Diagnostics)[^]). On each phase, you have to notify the rendering subsystem to re-render your window. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).



You should not assign different value of ScaleTransform to UIElement.RenderTransform in a loop; this is impossible. Instead, do it only once (one normal place for it, as well as for creation of a thread, in overridden OnContentRendered), and then, in the thread loop, change the scale factor Transform.ScaleX.

You need to pass an instance of Dispatcher and ScaleTransform to a thread. I explained a good way to do it based on the ThreadWrapper I proposed here: How to pass ref parameter to the thread[^].

[END EDIT #1]

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
.NET event on main thread,
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading.

If you do all that properly, your show may really impress people.

It's possible that someone could give you other solutions or give more detail on, say, 3D model approach…



Answered in detail in my new short (Tips & Tricks) article How to "Rotate" a WPF Window?

This article covers only more interesting "2D" approach with "pseudo-rotation" of a "pseudo-window" which produced a spinning impression, which I think is pleasing enough. The WPF 3D API approach will take a lot more effort and would be more trivial at the same time…

[END EDIT #2]

—SA


这篇关于如何在wpf中旋转窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆