2010-01-13 25 views
6

Vorrei comprendere i requisiti generali per il layout WPF/Silverlight per consentire di implementare le funzioni di zoom & pan (drag and zoom). Non intendo lo zoom & per un'immagine ma per un layout di pagina (finestra) totale (o parte di esso) con alcuni controlli.Controlli WPF e Silverlight e funzionalità di panoramica e zoom

Quali caratteristiche del layout e quali caratteristiche dei controlli personalizzati utilizzati rendono il layout fisso e lo zoom dello zoom & impossibile?

risposta

9

Regola generale

Con poche eccezioni, tutto in WPF può essere stroncato, ingrandita, ruotata, allungato, ecc al contenuto del vostro cuore. Questo include controlli singoli come Button, controlli composti come ListBox e contenitori come StackPanel.

Le eccezioni

Qui ci sono le eccezioni:

  1. Se si utilizza Adorner e la tua AdornerDecorator è al di fuori dell'area stroncato/zoom, poi i Adorners attaccati alla vostra zona stroncato/zoom pan ma non zoom. La soluzione è inserire un AdornerDecorator aggiuntivo all'interno dell'area panoramica/ingrandita.

  2. Se si utilizza un Popup, verrà visualizzato nella posizione panoramica/ingrandita del suo PlacementTarget ma non verrà ridimensionato. Inoltre non si muoverà mentre si esegue il pan dell'area che contiene il suo PlacementTarget (in pratica si trova nella sua superficie sopra il controllo target). Per ovviare a questo, utilizzare una tela di dimensioni zero con un ordine Z elevato, invece, quando si desidera che compaia qualcosa all'interno dell'area zoom/panoramica.

  3. Qualsiasi ContextMenu definito verrà visualizzato all'interno di un popup, pertanto le voci del menu mostreranno le dimensioni normali anche quando l'area su cui si fa clic è ingrandita o ridotta. A causa della natura di un menu di scelta rapida, questo è probabilmente un comportamento desiderabile. In caso contrario, è possibile avvolgere le voci di menu in un ViewBox e legare lo zoom allo zoom dell'area principale.

  4. Le tue descrizioni di strumenti mostreranno le dimensioni normali anche se l'interfaccia utente è panoramica o ingrandita. La stessa soluzione di ContextMenu.

  5. Se si è utilizzata l'integrazione di WinForms con i controlli e l'interfaccia utente legacy di WinForms integrati, non verranno correttamente spostati, ingranditi e agganciati in determinate situazioni. Esiste una tecnica avanzata per aggirare questo problema, in cui si implementa il controllo WinForms fuori schermo, quindi si utilizza BitBlt o copia simile l'immagine nella finestra come un'immagine e si inoltrano i clic del mouse e le sequenze di tasti alla finestra fuori schermo. Questo è un sacco di lavoro, però.

  6. Se si ignora WPF e si utilizza direttamente GDI + o DirectX o si utilizza Win32 hWnds per visualizzare il contenuto o l'interfaccia utente, il contenuto o l'interfaccia utente non saranno correttamente panoramici, ingranditi o ritagliati nella finestra a meno che non lo si faccia nell'interfaccia utente codice.

Note finali

  • Un buon WPF UI utilizza sempre i pannelli come griglia, DockPanel, ecc per disporre controlli in maniera flessibile in modo che si adattano automaticamente alle dimensioni del contenitore, piuttosto che utilizzare dimensioni e posizioni fisse. Questo vale anche per i contenuti interni dell'area panoramica/zoom, MA c'è un'eccezione a questa regola: l'elemento più esterno nell'area panoramica/zoom deve avere una dimensione specificata. Altrimenti cosa definirà l'area che viene spostata/ingrandita?

  • Il modo più semplice per implementare le funzioni di panoramica/zoom è di regolare il RenderTransform del controllo più esterno nell'area panoramica/zoom. Esistono molti modi per implementare i controlli per il panning e lo zoom, ad esempio è possibile utilizzare i pulsanti e gli slider della barra degli strumenti, le barre di scorrimento, la rotellina del mouse, la barra spaziatrice + trascinare per eseguire il panning, le aree trascinabili dell'interfaccia utente selezionata o qualsiasi combinazione di questi. Qualunque interfaccia tu scelga, ti basta aggiornare il RenderTransform in modo appropriato dal code-behind e sei a posto.

  • Se il meccanismo di panoramica selezionato è barre di scorrimento, è possibile utilizzare un ScrollViewer e utilizzare solo RenderTransform per lo zoom.

  • Accertarsi di aver impostato il ritaglio sull'area panoramica/zoom. Altrimenti, se si ingrandiscono o si spostano gli elementi dal lato, saranno comunque visibili al di fuori dell'area di panoramica/zoom.

+0

Ray, Grazie per il vostro tempo e gli sforzi per dare una risposta così dettagliata. +1 – rem

+0

'" C'è una tecnica avanzata per aggirare questo, dove si implementa il controllo WinForms fuori dallo schermo, quindi si usa BitBlt o simile copia l'immagine nella tua finestra come un'immagine, e fai avanzare i clic del mouse e le sequenze di tasti nella finestra fuori schermo Questo è un sacco di lavoro, però. " Avete riferimenti di persone che hanno fatto questo? I meccanismi di inoltro degli eventi, in particolare, sembrano ingannevoli. –

+0

@Russell: Una volta ho provato un codice che ha fatto questo, ma non l'ho scritto da solo e non so da nessuna parte online, puoi trovarne un esempio. Ricordo che il codice di inoltro degli eventi ha pubblicato semplici messaggi WM_ di basso livello, ad es. WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_KEYDOWN, ecc. –

1

Una veramente facile modo per implementare lo zoom in XAML è quello di utilizzare un Silverlight Viewbox. Questo ingrandisce lo XAML non i pixel. È possibile specificare il tratto da utilizzare e il ViewBox si ridimensionerà in base a questo (Riempimento, Nessuno, Uniforme ecc.). Ci sono alcuni fantastici post sul blog di Viewbox sul Web se cerchi Silverlight + Viewbox su Google.

Il panning è facilmente realizzabile con un meccanismo simile a trascinare e rilasciare e ci sono anche numerosi messaggi how-to blog su questo, disponibile tramite Google. È sufficiente catturare gli eventi MouseDown, MouseMove e MouseUp.

3

Usa una zona MultiScaleImage o di tela di canapa, e mettere tutto il necessario per pan e zoom in esso

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

Nell'uso codice fare un TranslateTransform e ScaleTransform in un TransformGroup di pan e zoom

Controllare out altro SO post o questa example o this one

2

In generale è possibile trattare qualsiasi insieme composito di elementi dell'interfaccia utente uguale trattereste un singolo UIElement così il caso di un'immagine non è molto diversa dal fare lo stesso per un'intera applicazione. Il modo migliore per gestire lo zoom in base all'input dell'utente (in contrapposizione al ridimensionamento automatico eseguito da Viewbox) è l'applicazione di ScaleTransform. Questo può essere impostato su un elemento padre di alto livello, come una griglia alla radice di un layout di finestra. Per la panoramica è possibile combinare in un TranslateTransform o in alcuni casi utilizzare un ScrollViewer per gestire lo spostamento della visualizzazione del contenuto.