2010-01-13 55 views
6

我想了解WPF/Silverlight佈局的一般要求,以便實現平移&縮放(拖動和縮放)功能。我並不意味着使用某些控件縮放圖像,而是使用全屏頁面(窗口)佈局(或其中的一部分)。WPF和Silverlight控件和佈局平移和縮放功能

佈局的哪些特徵以及使用過的自定義控件的哪些功能會使佈局固定,並且pan &縮放不可能?

回答

9

通則

除了少數例外,一切都在WPF可以平移,縮放,旋轉,伸展等,以你的心臟的內容。這包括像Button這樣的單一控件,像ListBox這樣的複合控件,以及像StackPanel這樣的容器。

例外

這裏是例外:

  1. 如果您使用的裝飾器,你的AdornerDecorator是平移/縮放區域外,那麼裝飾器連接到您的平移/縮放區域將平移但不縮放。解決方法是在平移/縮放區域內放置一個額外的AdornerDecorator。

  2. 如果您使用彈出窗口,它將顯示在其PlacementTarget的平移/縮放位置,但它本身不會被縮放。當您平移包含PlacementTarget的區域時(它基本上位於目標控件上方的自己表面中),它也不會移動。爲了解決這個問題,當想要在縮放/平移區域內彈出某些內容時,請使用高Z順序的零尺寸Canvas。

  3. 您定義的任何ContextMenu都會顯示在彈出框內,所以即使您點擊的區域被放大或縮小,菜單項也會顯示正常大小。由於上下文菜單的性質,這可能是理想的行爲。如果沒有,您可以將菜單項包裝到ViewBox中,並將縮放比例與主區域的縮放比例關聯起來。

  4. 即使用戶界面被平移或放大,您的工具提示也會顯示正常大小。與ContextMenu相同的解決方案。

  5. 如果您將WinForms集成用於集成的傳統WinForms控件和UI,則在某些情況下它們將無法正確平移,縮放和剪輯。有一種先進的技術可以解決這個問題,在屏幕上實現WinForms控件,然後使用BitBlt或類似的方法將圖像作爲圖像複製到窗口中,並將鼠標點擊和擊鍵轉發到屏幕外的窗口。不過,這是很多工作。

  6. 如果您繞過WPF並直接使用GDI +或DirectX,或者使用Win32 hWnds顯示內容或UI,則該內容或UI將不會被正確地平移,縮放或剪裁到窗口,除非您在界面中自己做碼。

最後說明

  • 好的WPF UI總是使用像電網,DockPanel中,等等面板以靈活的方式來佈置進行控制,使得它們自動地調整到容器的尺寸,而不是使用固定的大小和位置。對於平移/縮放區域的內部內容也是如此,但是此規則有一個例外:平移/縮放區域中最外面的元素必須具有指定的大小。否則,將定義被平移/縮小的區域是什麼?

  • 實現平移/縮放功能的簡單方法是調整平移/縮放區域中最外層控件的RenderTransform。有很多不同的方法可以實現平移和縮放的控件,例如,您可以使用工具欄按鈕和滑塊,滾動條,鼠標滾輪,空格鍵+拖動平移,可拖動的UI自身區域或這些的任意組合。無論您選擇哪種接口,只需從代碼隱藏中適當地更新RenderTransform,即可開始使用。

  • 如果您選擇的平移機制是滾動條,您可能需要使用ScrollViewer並且只使用RenderTransform進行縮放。

  • 確保您在平移/縮放區域設置了剪裁。否則,如果您放大或平移側面的項目,它們仍會在平移/縮放區域外可見。

+0

雷,感謝您的時間和努力,給出了這樣一個詳細的答案。 +1 – rem 2010-01-22 15:06:44

+0

''有一種先進的技術可以解決這個問題,在屏幕上實現WinForms控件,然後使用BitBlt或類似的方法將圖像作爲圖像複製到窗口中,並將鼠標點擊和擊鍵轉發到屏幕外的窗口。這是很多工作,但是。「' 你有任何人誰已經這樣做的參考?事件轉發機制,特別是,似乎很棘手。 – 2010-02-23 03:15:38

+0

@Russell:我曾經試過一些代碼,但是我沒有自己寫,而且我也不知道在線的任何地方都可以找到它的例子。我記得事件轉發代碼發佈了簡單的低級別WM_消息,例如。 WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_KEYDOWN等。 – 2010-02-23 04:44:36

1

實現XAML縮放的一個非常簡單的方法是使用Silverlight ViewBox。這會縮放XAML而不是像素。您可以指定要使用的拉伸,並且ViewBox將基於此進行縮放(填充,無,統一等)。如果您在Google上搜索Silverlight + Viewbox,則Web上會有一些很棒的Viewbox博客文章。

平移很容易通過類似的拖放機制來完成,並且還有大量關於此操作的how-to博客文章,可通過Google獲得。只需等於捕獲MouseDown,MouseMove和MouseUp事件。

3

使用MultiScaleImage或畫布的區域,然後將你需要平移和縮放它的一切

<Canvas x:Name="panZoomPanel" Background="Transparent"> 
</Canvas> 

在代碼中使用做出TranslateTransform,並在的TransformGroup一個ScaleTransform平移和縮放

檢查out other SO post或此examplethis one

2

一般來說,您可以對待任何複合UI元素集,就像您將要處理單個UIElement一樣,的圖像與完成整個應用程序的效果並不完全不同。處理基於用戶輸入的縮放的最佳方式(與Viewbox自動縮放相反)是應用ScaleTransform。這可以在高層次的父元素上設置,例如窗口布局根部的網格。對於平移,您可以在TranslateTransform中進行合併,或者在某些情況下使用ScrollViewer來處理移動內容的視圖。