布局的哪些特征以及使用的自定义控件的哪些特征会使布局固定且无法进行平移和缩放?
通用规则
除了极少数情况外,WPF 中的所有内容都可以随意平移、缩放、旋转、拉伸等。这包括单个控件(如 Button)、复合控件(如 ListBox)和容器(如 StackPanel)。
特殊情况
以下是特殊情况:
如果您正在使用 Adorner,并且您的 AdornerDecorator 在已平移/缩放的区域之外,则附加到已平移/缩放区域的 Adorners 将进行平移但不会缩放。解决方法是在已平移/缩放区域内添加一个额外的 AdornerDecorator。
如果您使用 Popup,则它将显示在其 PlacementTarget 的已平移/缩放位置,但它本身不会缩放。当您平移包含其 PlacementTarget 的区域时,它也不会移动(基本上它坐在自己的表面上方)。要解决此问题,请在需要在缩放/平移区域中弹出某些内容时使用零大小 Canvas 和高 Z 顺序。
您定义的任何 ContextMenu 都将显示在弹出窗口中,因此即使单击的区域缩放或放大,菜单项也将以正常大小显示。由于上下文菜单的性质,这可能是期望的行为。如果不是,您可以将菜单项包装在 ViewBox 中,并将缩放与主区域的缩放绑定。
您的 ToolTips 将以正常大小显示,即使 UI 被平移或缩放。解决方案与 ContextMenu 相同。
如果您使用 WinForms 集成来集成旧版 WinForms 控件和 UI,则它们在某些情况下将无法正常平移、缩放和裁剪。有一种高级技术可解决此问题,即将 WinForms 控件在屏幕外实现,然后使用 BitBlt 或类似的方法将图像复制到窗口中作为图像,并将鼠标点击和按键操作转发到屏幕外窗口。但这需要大量工作。
如果绕过WPF直接使用GDI+或DirectX,或者使用Win32 hWnds显示内容或UI,则该内容或UI将不会正确地滚动、缩放或剪切到窗口,除非在您的接口代码中自己完成。
最后注意事项
一个好的WPF UI总是使用诸如Grid、DockPanel等面板来以灵活的方式布置控件,使它们自动适应容器大小,而不是使用固定的大小和位置。这也适用于您的 pan/zoom 区域的内部内容,但是有一个例外:您的 pan/zoom 区域中的最外层元素必须具有指定的大小。否则,什么来定义被平移/缩放的区域呢?
实现平移/缩放功能的简单方法是调整 pan/zoom 区域中最外层控件的 RenderTransform。可以使用许多不同的方式来实现平移和缩放的控件,例如可以使用工具栏按钮和滑块、滚动条、鼠标滚轮、空格键+拖动进行平移,被平移 UI 本身的可拖动区域,或以上任意组合。无论您选择哪种界面,只需从代码后台适当地更新 RenderTransform,您就可以开始工作了。
如果您选择的平移机制是滚动条,则可能希望使用 ScrollViewer 并仅使用 RenderTransform 进行缩放。
请确保在 pan/zoom 区域上设置剪辑。否则,如果您缩放或平移超出边界的项目,它们仍将在 pan/zoom 区域外可见。
在XAML中实现缩放的一种非常简单的方法是使用Silverlight ViewBox。这将缩放XAML而不是像素。您可以指定要使用的拉伸方式,ViewBox将根据此进行缩放(填充、无、均匀等)。如果您在Google上搜索Silverlight+Viewbox,就会发现一些很棒的Viewbox博客文章。
通过类似于拖放的机制轻松实现平移,并且还有许多如何博客文章可供参考,可以通过Google获得。只需捕获MouseDown、MouseMove和MouseUp事件即可。