Il presente articolo è stato tradotto automaticamente.
Nuove frontiere per l'interfaccia utente
Vantaggi e svantaggi di ItemsControl
Charles Petzold
Scaricare il codice di esempio
Se qualcuno Chiedi quali singola classe epitomizes più la potenza e la flessibilità di Windows Presentation Foundation (WPF) e Silverlight, innanzitutto direi che è una domanda stupidi e quindi rispondere “ DataTemplate. ” senza immediatamente del momento,
Un DataTemplate è essenzialmente una struttura visiva di elementi e controlli.DataTemplates utilizzato dai programmatori per dare un aspetto visivo per gli oggetti dati non visivo.Le proprietà degli elementi nella struttura visiva sono collegate tramite associazioni alle proprietà degli oggetti dati.Sebbene il modello di dati viene in genere utilizzato per definire l'aspetto degli oggetti ItemsControl o un controllo ListBox (una delle classi che derivano da ItemsControl), è possibile utilizzare anche un DataTemplate per definire l'aspetto di un oggetto, impostato la proprietà Content di un ContentControl o un derivato ContentControl, ad esempio un pulsante.
Creazione di un modello di dati, o qualsiasi altro tipo di derivazione FrameworkTemplate quali ControlTemplate o HierarchicalDataTemplate — è uno di alcune attività di programmazione Silverlight che non può essere effettuata nel codice.È necessario utilizzare XAML.È possibile creare modelli di WPF interamente nel codice utilizzando ElementFactory Framework una volta, ma penso che è stato l'unico effettivamente pubblicare esempi (nei capitoli 11 e 13 16 del mio libro “ Applications = Code + Markup ” [Microsoft Press, 2006]) e la tecnica ora obsoleta.
Si desidera visualizzare in questo articolo è una variante di trascinamento e rilascio: Si sposta semplicemente un elemento da uno ItemsControl a altro.Tuttavia, l'obiettivo principale è quello di implementare l'intero processo con un fluido interamente aspetto che sembra naturale e dove nulla improvvisamente jerks o scomparirà.Naturalmente, “ aspetto naturale ” spesso diligentemente viene ottenuta e qualsiasi programma verranno privilegiate fluidity deve evitare di rivelare tutti machinations difficile subito sotto la superficie.
Una combinazione di tecniche che ho illustrato nel scorso articolo del mese (“ Thinking esterno griglia di ”) verranno utilizzati come anche un DataTemplate è condivisa tra due ItemsControls e un ContentControl, ovvero un concetto essenziale per l'intera applicazione.
Layout del programma
Il codice scaricabile che accompagna questo articolo contiene un singolo progetto Silverlight denominato ItemsControlTransitions, è possibile eseguire dal sito Web all'indirizzo charlespetzold.com/silverlight/ItemsControlTransitions2.(Spiegherò il “ 2 ” alla fine di questo URL successiva.) È possibile utilizzare gli stessi concetti presentati in questo programma di Silverlight in un'applicazione WPF.
Il programma visualizza due controlli di elementi, entrambi contenuti in ScrollViewers.È possibile visualizzare ItemsControl a sinistra come un vendita di produrre “ mercato ”.Quello a destra è “ carrello. ” È possibile utilizzare il mouse per prelevare gli articoli produrre dal mercato e spostarli nel carrello.Figura 1 Visualizza l'elemento con transizione dal mercato al carrello.
Figura 1 Il Display ItemsControlTransitions
Sebbene l'elemento con è stato spostato all'esterno del mercato, notare le differenze in ItemsControl che continua a indicare l'origine dell'elemento.Se l'utente rilascia il pulsante del mouse prima che l'elemento trascinato è stato posizionato sul controllo articoli al carrello, il programma Anima l'elemento nel mercato.Solo quando l'elemento viene trascinato nel carrello tale divario chiudere, nuovamente con un'animazione.A seconda di dove l'elemento viene rilasciato, apre un divario animata per ricevere l'articolo e viene animato l'elemento nella posizione desiderata.
Una volta che un elemento è stato spostato dal mercato, non esiste più esiste ma è un dettaglio di programma potrebbe essere modificato facilmente.Esiste alcuno strumento per rimuovere un elemento dal carrello e riportarlo nel mercato, ma tale funzionalità o qualcosa di simile potrebbe essere aggiunto abbastanza facilmente anche.
Figura 2 Mostra la maggior parte dei file XAML responsabile per il layout di base.(Mancanti sono due storyboard con sette animazioni che verrà descritto più avanti).
Figura 2 di file XAML parziale responsabile per il layout di base
<UserControl x:Class="ItemsControlTransitions.MainPage"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Name="this">
<UserControl.Resources>
<DataTemplate x:Key="produceDataTemplate">
<Border Width="144"
Height="144"
BorderBrush="Black"
BorderThickness="1"
Background="AliceBlue"
Margin="6">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0"
Source="{Binding Photo}" />
<TextBlock Grid.Row="1"
Text="{Binding Name}"
HorizontalAlignment="Center" />
</Grid>
</Border>
</DataTemplate>
...
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ScrollViewer HorizontalAlignment="Left"
Margin="48">
<ItemsControl Name="market"
ItemTemplate="{StaticResource produceDataTemplate}"
Width="156"
MouseLeftButtonDown="OnMarketItemsControlMouseLeftButtonDown" />
</ScrollViewer>
<ScrollViewer HorizontalAlignment="Right"
Margin="48">
<ItemsControl Name="basket"
ItemTemplate="{StaticResource produceDataTemplate}"
Width="156" />
</ScrollViewer>
<Canvas Name="dragCanvas">
<ContentControl Name="dragControl"
ContentTemplate="{StaticResource produceDataTemplate}"
Visibility="Collapsed" />
</Canvas>
</Grid>
</UserControl>
La sezione risorse contiene un DataTemplate per visualizzare gli articoli di produzione e viene impostato un riferimento a questa risorsa alla proprietà ItemsTemplate di due ItemsControls.
Inoltre, un oggetto Canvas copre l'intera area occupata dal programma.Si verrà richiamare dal scorso articolo del mese come utilizzare un oggetto Canvas agli elementi host che devono “ float ” rispetto al resto dell'interfaccia utente.Il solo figlio di questa area è un ContentControl, con relativa ContentTemplate inoltre impostata su tale modello di dati.Ma viene impostata la proprietà Visibility su Collapsed questo ContentControl è inizialmente invisibile.
I controlli che derivano da ContentControl comuni nelle applicazioni WPF e Silverlight, ma di non sono spesso che vedere di un ContentControl stesso.Pare essere particolarmente utile se si desidera visualizzare un oggetto utilizzando un DataTemplate.Visivamente, è molto simile a un singolo elemento in ItemsControl.
Il programma inizia dal caricamento in un piccolo database XML di alcuni consentono di ottenere, utilizzando gli stessi file dal progetto ItemsControlPopouts nel scorso articolo del mese e quindi riempire il mercato ItemsControl con oggetti di tipo ProduceItem.Questa classe dispone di proprietà Name e foto che DataTemplate fa riferimento per visualizzare ogni elemento.
Estrazione di elementi da ItemsControl
ItemsControl per il mercato dispone di un gestore per MouseLeftButtonDown.Nella ricezione di questo evento, il programma deve dislodge un elemento da confini quattro muro di ItemsControl e consentire di tenere traccia del mouse.Ma effettivamente Impossibile rimuovere l'elemento da ItemsControl o il divario chiuderà automaticamente.
Come è stato illustrato nel scorso articolo del mese, è possibile accedere alla proprietà ItemContainerGenerator di ItemsControl per ottenere una classe che è possibile associare ogni elemento in ItemsControl con la struttura ad albero visuale generata per visualizzare quel particolare elemento.Questa struttura visiva è un elemento principale di tipo ContentPresenter.
Il primo impulse era per applicare un TranslateTransform alla proprietà RenderTransform di ContentPresenter, in modo da float di fuori di ItemsControl.So dall'esperienza, tuttavia, che questa non funziona affatto.Il problema non è ItemsControl stesso, il problema è ScrollViewer, quale importanza clip figli alla parte interna.(Informazioni sulle motivazioni di questo ritaglio a breve).
Invece il programma copia il ContentControl ProduceItem selezionato in ItemsControl e posiziona il ContentControl con precisione su ContentPresenter dell'elemento selezionato.(Il programma può ottenere la posizione di ContentPresenter rispetto all'area di utilizzando il metodo TransformToVisual sempre pratico.) È necessario richiamare file XAML imposta la proprietà Visibility di ContentControl compressa, ma ora il programma disattiva tale proprietà Visible.
Contemporaneamente, viene effettuata invisibile ContentPresenter in ItemsControl.In WPF, è possibile farlo impostando la proprietà Visibility su Hidden, che rende l'elemento invisibile, ma in caso contrario genera dimensione dell'elemento a essere osservati per scopi di layout.La proprietà Visibility di Silverlight non dispone di un'opzione nascosto e se si imposta la proprietà Visibility di ContentPresenter su Collapsed, verrà chiuso il divario.Invece possibile simulare un'impostazione di visibilità di nascosto impostando semplicemente la proprietà Opacity su zero.L'elemento è ancora presente, ma è invisibile.Sperimentare il programma, si scoprirà che il passaggio dall'elemento in ItemsControl ContentControl trascinabile è imperceptible.
A questo punto, ContentPresenter in ItemsControl Visualizza nulla, ma un buco vuoto e ContentControl visualizzazione dell'elemento ora può essere trascinato sullo schermo con il mouse.
Selezione di elementi
Quando era scritto libri sulle Win16 e Win32 API, dedicato interi capitoli che illustrano come utilizzare le barre di scorrimento per visualizzare testo in una finestra non possono essere presenti.Oggi abbiamo semplicemente utilizzare un elemento ScrollViewer e tutti gli utenti è molto utile, me la maggior parte di tutti.
Nonostante il ruolo fondamentale nel layout WPF e Silverlight, può essere difficile da utilizzare a volte ScrollViewer. Ha alcune caratteristiche che possono essere un po' puzzling e questo programma rivela uno di essi.Vedere se è possibile prevedere il problema.
Abbiamo lasciato l'utente sposta un elemento di produrre sullo schermo con il mouse.Se l'utente rilascia l'elemento di produrre un punto in ItemsControl che rappresenta il carrello, diventa parte dell'insieme.(Ulteriori informazioni su questo processo poco.) In caso contrario, il programma Anima l'elemento di origine utilizzando due animazioni in returnToOriginStoryboard in MainPage.xaml.Al termine dell'animazione, la proprietà Opacity di ContentPresenter è impostata su uno, la proprietà Visibility di ContentControl è impostata su Collapsed e l'evento di trascinamento viene conclusa con tutto a normale.
Per determinare se l'articolo di produzione viene rilasciato in ItemsControl, viene calcolato un oggetto Rect che rappresenta la posizione e le dimensioni di ContentControl trascinato e un altro oggetto Rect che rappresenta la posizione e le dimensioni di ItemsControl.In entrambi i casi, il programma utilizza il metodo TransformToVisual per ottenere la posizione dell'angolo superiore sinistro del controllo, ovvero il punto (0, 0), ovvero rispetto alla pagina e proprietà ActualWidth e ActualHeight per ottenere le dimensioni del controllo.Metodo Intersect della struttura Rect calcola quindi un'intersezione di due rettangoli, che sarà non vuoto se alcuni sovrapposizione.
Tranne quando ItemsControl ha più elementi di quanti possano essere registrati nello spazio verticale consentito per tale questo funziona correttamente.Elemento ScrollViewer quindi interviene per rendere visibile la barra di scorrimento verticale in modo che gli elementi che è possibile scorrere in azione.Tuttavia, ItemsControl l'elemento ScrollViewer ritiene effettivamente per superare da visualizzare; in un certo senso reale, ScrollViewer fornendo una finestra visibile (denominata “ riquadro ”) in ItemsControl.Le informazioni di posizione e dimensioni che ottenere per tale ItemsControl sempre indicano la dimensione completa (denominato dimensioni “ extent ”) e non la dimensione del riquadro di visualizzazione.
Ecco perché ScrollViewer è figlio del clip.Se si è lavorato con Silverlight per un periodo di tempo, potrebbe essere particolarmente abituati a un determinato laxity riguardo alla visualizzazione degli elementi figlio.È possibile utilizzare quasi sempre RenderTransform per uscire dai limiti del padre.Tuttavia ScrollViewer è indubbiamente clip o semplicemente non può funzionare a destra.
Ciò significa che non è possibile utilizzare le dimensioni apparenti di ItemsControl per determinare un trascinamento valida, perché in alcuni casi ItemsControl estende sopra e sotto l'elemento ScrollViewer.Per questo motivo, il programma determina un rettangolo di destinazione valido in base alle dimensioni orizzontali di ItemsControl, poiché si desidera escludere l'area occupata dalla barra di scorrimento, ma le dimensioni verticali di ScrollViewer.
Quando viene eliminata la ContentControl in ItemsControl, potrebbe essere sovrapposte due elementi esistenti o uno se viene rilasciato in alto o in basso di stack di elementi o nessuno affatto.Volevo inserire il nuovo elemento nel punto in cui viene rilasciato, quale necessario enumerare gli elementi in ItemsControl (e i relativi oggetti ContentPresenter associati) e determinare un buon indice per inserire il nuovo elemento più vicino.(Il metodo GetBasketDestinationIndex è responsabile della determinazione di questo indice.) Dopo l'inserimento, l'elemento ContentPresenter associati con questo nuovo elemento viene assegnato un'altezza pari a zero iniziale e un'opacità pari a zero, in modo che non sia visibile inizialmente.
Dopo l'inserimento del programma avvia lo storyboard denominato transferToBasketStoryboard con cinque animazioni: uno per ridurre l'altezza di ContentPresenter invisibile in ItemsControl per il mercato e un'altra per aumentare l'altezza di ContentPresenter invisibile appena creato nel carrello ItemsControl; e altre due per animare il Canvas.Left e Canvas.Top allegato proprietà diapositiva il ContentControl nella posizione desiderata.(Tratterò l'animazione quinto poco.) Figura 3 Mostra il divario di ampliamento di ContentControl raggiunge la destinazione.
Figura 3 dell'animazione per spostare un nuovo elemento in place
Al termine dell'animazione, nuovo ContentPresenter viene fornita un'opacità di uno il ContentControl viene specificata una visibilità di Collapsed e ora siamo a appena si utilizzano due ItemsControls normale all'interno ScrollViewers.
Alto e basso problemi
In questo articolo fornito di charlespetzold.com/silverlight/ItemsControlTransitions2 di URL per provare il programma.Charlespetzold.com/silverlight/ItemsControlTransitions , senza “ 2 ” alla fine, è possibile eseguire una versione precedente del programma.Utilizzando questa versione precedente, spostarsi su diversi produrre articoli al carrello, sufficienti per visualizzare la barra di scorrimento verticale.Ora trascinare un'altra e posizionarla straddling fondo ScrollViewer.Quando si rilascia il pulsante del mouse, il ContentControl Sposta giù verso un'area di ItemsControl che è invisibile e improvvisamente scompare.L'elemento è stato inserito correttamente (come è possibile verificare lo scorrimento verso il basso), ma non molto elegantemente.
Scorrere ScrollViewer ora in modo che il primo elemento è solo parzialmente visibile. Spostare un altro elemento dal carrello e posizionarla in modo verrà inserita prima di tale elemento.Il nuovo elemento diapositive in ItemsControl, ma non è completamente visibile.Non è abbastanza errato come problema nella parte inferiore di ItemsControl, ma deve comunque alcuni argomenti della Guida.
La correzione?È necessario un modo per scorrere a livello di codice l'elemento ScrollViewer.La quantità di lo scorrimento verticale attualmente in vigore per un elemento ScrollViewer viene fornita tramite la proprietà VerticalOffset.Questo numero è un offset dall'inizio dell'intero ItemsControl positivo nella posizione del controllo viene visualizzato nella parte superiore dell'elemento ScrollViewer.
Non sarebbe bello semplicemente animare proprietà VerticalOffset?Purtroppo, solo la funzione di accesso get è pubblica.Fortunatamente, è possibile scorrere a livello di codice l'elemento ScrollViewer, ma è necessario chiamare un metodo denominato ScrollToVerticalOffset.
Per eseguire questo processo poco scorrevole tramite la funzionalità di animazione di Silverlight, ho definito una proprietà di dipendenza denominata Scroll in MainPage stesso.Nel file XAML assegnato un nome “ questo ” nella pagina e definito una quinta animazione in transferToBasketStoryboard questa proprietà di destinazione:
<DoubleAnimation x:Name="scrollItemsControlAnima"
Storyboard.TargetName="this"
Storyboard.TargetProperty="Scroll" />
Override OnMouseLeftButtonUp viene calcolato da e per i valori di questa animazione. (È possibile confrontare l'effetto di animazione aggiuntiva da impostare come commento il blocco di codice che inizia con il commento “ calcola ScrollViewer scorrevole animazione ”.) Come questa proprietà Scroll è animata, il gestore di proprietà modificata chiama il metodo ScrollToVerticalOffset di ScrollViewer con valore animato.
Verso un'interfaccia utente di fluido
Molti, molti anni fa, i computer erano molto più lenti sono ora e mai niente è accaduto nella schermata era molto startling. Oggi, programmi possono implementare interfacce utente modificare completamente i relativi aspetti di intermittenza di un occhio. Ma è anche insoddisfacenti. Spesso anche non possiamo vedere cosa succede, così ora abbiamo trovare necessari deliberatamente rallentare l'interfaccia utente ed effettuare transizioni più fluido e naturale. Silverlight 4 introdotte alcune funzionalità “ fluido UI ” sto non differita discutere, ma anche in Silverlight 3 è possibile iniziare il viaggio in quella direzione.
Charles Petzold* è consulente redattore esperti di* MSDN Magazine*.*Egli è attualmente scrivendo “ Programming Windows telefono 7 Series ” che verrà pubblicato come un e-book scaricabile gratuitamente nell'autunno del 2010. Una versione di anteprima è disponibile tramite di charlespetzold.com il suo sito Web.