ListView
L'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) ListView visualizza un elenco verticale scorrevole di elementi di dati selezionabili. Mentre ListView gestisce l'aspetto dell'elenco, l'aspetto di ogni elemento nell'elenco è definito da un DataTemplate oggetto che usa un Cell oggetto per visualizzare gli elementi. .NET MAUI include tipi di cella per visualizzare combinazioni di testo e immagini ed è anche possibile definire celle personalizzate che visualizzano qualsiasi contenuto desiderato. ListView include anche il supporto per la visualizzazione di intestazioni e piè di pagina, dati raggruppati, aggiornamenti pull-to-refresh e voci di menu di scelta rapida.
La ListView classe deriva dalla ItemsView<Cell>
classe , da cui eredita le proprietà seguenti:
ItemsSource
, di tipoIEnumerable
, specifica la raccolta di elementi da visualizzare e ha un valore predefinito .null
ItemTemplate
, di tipo DataTemplate, specifica il modello da applicare a ogni elemento della raccolta di elementi da visualizzare.
ListView definisce le proprietà seguenti:
Footer
, di tipoobject
, specifica la stringa o la visualizzazione che verrà visualizzata alla fine dell'elenco.FooterTemplate
, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggettoFooter
.GroupHeaderTemplate
, di tipo DataTemplate, definisce l'oggetto DataTemplate usato per definire l'aspetto dell'intestazione di ogni gruppo. Questa proprietà si escludono a vicenda con laGroupDisplayBinding
proprietà . Pertanto, l'impostazione di questa proprietà verrà impostata suGroupDisplayBinding
null
.HasUnevenRows
, di tipobool
, indica se gli elementi nell'elenco possono avere righe di altezze diverse. Il valore predefinito di questa proprietà èfalse
.Header
, di tipoobject
, specifica la stringa o la visualizzazione che verrà visualizzata all'inizio dell'elenco.HeaderTemplate
, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggettoHeader
.HorizontalScrollBarVisibility
, di tipoScrollBarVisibility
, indica quando la barra di scorrimento orizzontale sarà visibile.IsGroupingEnabled
, di tipobool
, indica se i dati sottostanti devono essere visualizzati in gruppi. Il valore predefinito di questa proprietà èfalse
.IsPullToRefreshEnabled
, di tipobool
, indica se l'utente può scorrere verso il basso per fare in modo che l'oggetto ListView aggiorni i dati. Il valore predefinito di questa proprietà èfalse
.IsRefreshing
, di tipobool
, indica se l'oggetto ListView è attualmente aggiornato. Il valore predefinito di questa proprietà èfalse
.RefreshCommand
, di tipo ICommand, rappresenta il comando che verrà eseguito quando viene attivato un aggiornamento.RefreshControlColor
, di tipo Color, determina il colore della visualizzazione di aggiornamento visualizzata mentre si verifica un aggiornamento.RowHeight
, di tipoint
, determina l'altezza di ogni riga quandoHasUnevenRows
èfalse
.SelectedItem
, di tipoobject
, rappresenta l'elemento attualmente selezionato in ListView.SelectionMode
, di tipoListViewSelectionMode
, indica se gli elementi possono essere selezionati in ListView o meno. Il valore predefinito di questa proprietà èSingle
.SeparatorColor
, di tipo Color, definisce il colore della barra che separa gli elementi nell'elenco.SeparatorVisibility
, di tipoSeparatorVisibility
, definisce se i separatori sono visibili tra gli elementi.VerticalScrollBarVisibility
, di tipoScrollBarVisibility
, indica quando la barra di scorrimento verticale sarà visibile.
Tutte queste proprietà sono supportate da BindableProperty oggetti, il che significa che possono essere destinazioni di data binding e stili.
Definisce inoltre ListView le proprietà seguenti che non sono supportate dagli BindableProperty oggetti :
GroupDisplayBinding
, di tipoBindingBase
, associazione da usare per visualizzare l'intestazione del gruppo. Questa proprietà si escludono a vicenda con laGroupHeaderTemplate
proprietà . Pertanto, l'impostazione di questa proprietà verrà impostata suGroupHeaderTemplate
null
.GroupShortNameBinding
, di tipoBindingBase
, l'associazione per il nome da visualizzare in jump list raggruppate.CachingStrategy
, di tipoListViewCachingStrategy
, definisce la strategia di riutilizzo delle celle di ListView. Questa proprietà è di sola lettura.
ListView definisce gli eventi seguenti:
ItemAppearing
, generato quando viene aggiunta la rappresentazione visiva di un elemento al layout visivo dell'oggetto ListView. L'oggettoItemVisibilityEventArgs
che accompagna questo evento definisceItem
le proprietà eIndex
.ItemDisappearing
, generato quando la rappresentazione visiva di un elemento viene rimossa dal layout visivo dell'oggetto ListView. L'oggettoItemVisibilityEventArgs
che accompagna questo evento definisceItem
le proprietà eIndex
.ItemSelected
, generato quando viene selezionato un nuovo elemento nell'elenco. L'oggettoSelectedItemChangedEventArgs
che accompagna questo evento definisceSelectedItem
le proprietà eSelectedItemIndex
.ItemTapped
, generato quando viene toccato un elemento nell'oggetto ListView . L'oggettoItemTappedEventArgs
che accompagna questo evento definisceGroup
le proprietà ,Item
eItemIndex
.Refreshing
, generato quando viene attivata un'operazione pull per l'aggiornamento in ListView.Scrolled
, . L'oggettoScrolledEventArgs
che accompagna questo evento definisceScrollX
le proprietà eScrollY
.ScrollToRequested
. L'oggettoScrollToRequestedEventArgs
che accompagna questo evento definisce Elementle proprietà ,Position
Mode
,ScrollY
ScrollX
, , eShouldAnimate
.
Popolare un controllo ListView con i dati
Un ListView oggetto viene popolato con i dati impostando la relativa ItemsSource
proprietà su qualsiasi raccolta che implementa IEnumerable
.
Importante
ListView Se è necessario aggiornare quando vengono aggiunti, rimossi o modificati elementi nella raccolta sottostante, la raccolta sottostante deve essere una IEnumerable
raccolta che invia notifiche di modifica delle proprietà, ad esempio ObservableCollection
.
ListView può essere popolato con i dati usando il data binding per associarne la ItemsSource
proprietà a una IEnumerable
raccolta. In XAML questo risultato viene ottenuto con l'estensione di Binding
markup:
<ListView ItemsSource="{Binding Monkeys}" />
Il codice C# equivalente è il seguente:
ListView listView = new ListView();
listView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
In questo esempio, i dati della ItemsSource
proprietà vengono associati alla Monkeys
proprietà del modello di visualizzazione connesso.
Nota
Le associazioni compilate possono essere abilitate per migliorare le prestazioni del data binding nelle applicazioni MAUI .NET. Per altre informazioni, vedere Binding compilati.
Per altre informazioni sul data binding, vedere Data binding.
Definire l'aspetto dell'elemento
L'aspetto di ogni elemento in ListView può essere definito impostando la ItemTemplate
proprietà su :DataTemplate
<ListView ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Gli elementi specificati nell'oggetto DataTemplate definiscono l'aspetto di ogni elemento nell'elenco e l'elemento figlio di DataTemplate deve essere un Cell oggetto . Nell'esempio il layout all'interno di DataTemplate è gestito da un oggetto Grid. Grid Contiene un Image oggetto e due Label oggetti, che vengono associati alle proprietà della Monkey
classe :
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
Lo screenshot seguente mostra il risultato della creazione di modelli per ogni elemento nell'elenco:
Per altre informazioni sui modelli di dati, vedere Modelli di dati.
Cells
L'aspetto di ogni elemento in un ListView oggetto è definito da un DataTemplateoggetto e DataTemplate deve fare riferimento a una Cell classe per visualizzare gli elementi. Ogni cella rappresenta un elemento di dati nell'oggetto ListView. .NET MAUI include le celle predefinite seguenti:
- TextCell, che visualizza il testo primario e secondario in righe separate.
- ImageCell, che visualizza un'immagine con testo primario e secondario su righe separate.
- SwitchCell, che visualizza il testo e un interruttore che può essere attivato o disattivato.
- EntryCell, che visualizza un'etichetta e un testo modificabili.
- ViewCell, ovvero una cella personalizzata il cui aspetto è definito da un oggetto View. Questo tipo di cella deve essere usato quando si desidera definire completamente l'aspetto di ogni elemento in un oggetto ListView.
In genere, SwitchCell e EntryCell verranno usati solo in e TableView non verranno usati in un oggetto ListView. Per altre informazioni su SwitchCell e EntryCell, vedere TableView.
Cella di testo
Un TextCell oggetto visualizza il testo primario e secondario su righe separate. TextCell definisce le proprietà seguenti:
Text
, di tipostring
, definisce il testo primario da visualizzare.TextColor
, di tipo Color, rappresenta il colore del testo primario.Detail
, di tipostring
, definisce il testo secondario da visualizzare.DetailColor
, di tipo Color, indica il colore del testo secondario.Command
, di tipo ICommand, definisce il comando eseguito quando viene toccata la cella.CommandParameter
, di tipoobject
, rappresenta il parametro passato al comando .
Queste proprietà sono supportate da BindableProperty oggetti, il che significa che possono essere destinazioni di data binding e stili.
Nell'esempio seguente viene illustrato l'uso di per TextCell definire l'aspetto degli elementi in un ListViewoggetto :
<ListView ItemsSource="{Binding Food}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}"
Detail="{Binding Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Lo screenshot seguente mostra l'aspetto della cella risultante:
Cella Image
Un ImageCell oggetto visualizza un'immagine con testo primario e secondario su righe separate. ImageCell eredita le proprietà da TextCelle definisce la ImageSource proprietà di tipo ImageSource, che specifica l'immagine da visualizzare nella cella. Questa proprietà è supportata da un BindableProperty oggetto , il che significa che può essere la destinazione dei data binding e essere stilizzato.
Nell'esempio seguente viene illustrato l'uso di un ImageCell oggetto per definire l'aspetto degli elementi in un ListViewoggetto :
<ListView ItemsSource="{Binding Food}">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding Image}"
Text="{Binding Name}"
Detail="{Binding Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Lo screenshot seguente mostra l'aspetto della cella risultante:
Visualizzare la cella
Un ViewCell oggetto è una cella personalizzata il cui aspetto è definito da un oggetto View. ViewCell definisce una View proprietà di tipo View, che definisce la visualizzazione che rappresenta il contenuto della cella. Questa proprietà è supportata da un BindableProperty oggetto , il che significa che può essere la destinazione dei data binding e essere stilizzato.
Nota
La View proprietà è la proprietà content della ViewCell classe e pertanto non deve essere impostata in modo esplicito da XAML.
Nell'esempio seguente viene illustrato l'uso di per ViewCell definire l'aspetto degli elementi in un ListViewoggetto :
<ListView ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
All'interno di , il ViewCelllayout può essere gestito da qualsiasi layout MAUI .NET. In questo esempio il layout viene gestito da un oggetto Grid. Grid Contiene un Image oggetto e due Label oggetti associati alle proprietà della Monkey
classe .
Lo screenshot seguente mostra il risultato della creazione di modelli per ogni elemento nell'elenco:
Scegliere l'aspetto dell'elemento in fase di esecuzione
L'aspetto di ogni elemento in può essere scelto in ListView fase di esecuzione, in base al valore dell'elemento, impostando la ItemTemplate
proprietà su un DataTemplateSelector oggetto :
<ContentPage ...
xmlns:templates="clr-namespace:ListViewDemos.Templates">
<ContentPage.Resources>
<DataTemplate x:Key="AmericanMonkeyTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="OtherMonkeyTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<templates:MonkeyDataTemplateSelector x:Key="MonkeySelector"
AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
</ContentPage.Resources>
<Grid Margin="20">
<ListView ItemsSource="{Binding Monkeys}"
ItemTemplate="{StaticResource MonkeySelector}" />
</Grid>
</ContentPage>
La ItemTemplate
proprietà è impostata su un MonkeyDataTemplateSelector
oggetto . L'esempio seguente illustra la MonkeyDataTemplateSelector
classe :
public class MonkeyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate AmericanMonkey { get; set; }
public DataTemplate OtherMonkey { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
}
}
La MonkeyDataTemplateSelector
classe definisce AmericanMonkey
e OtherMonkey
DataTemplate proprietà impostate su modelli di dati diversi. L'override OnSelectTemplate
restituisce il AmericanMonkey
modello, che visualizza il nome della scimmia e la posizione in teal, quando il nome della scimmia contiene "America". Quando il nome della scimmia non contiene "America", l'override OnSelectTemplate
restituisce il OtherMonkey
modello, che visualizza il nome della scimmia e la posizione in argento:
Per altre informazioni sui selettori di modelli di dati, vedere Creare un oggetto DataTemplateSelector.
Rispondere alla selezione di elementi
Per impostazione predefinita, ListView la selezione è abilitata. Tuttavia, questo comportamento può essere modificato impostando la SelectionMode
proprietà . L'enumerazione ListViewSelectionMode
definisce i membri seguenti:
None
– indica che non è possibile selezionare gli elementi.Single
: indica che è possibile selezionare un singolo elemento, con l'elemento selezionato evidenziato. Questo è il valore predefinito.
ListView definisce un ItemSelected
evento generato quando la SelectedItem
proprietà viene modificata, a causa della selezione di un elemento dall'elenco da parte dell'utente o quando un'app imposta la proprietà. L'oggetto SelectedItemChangedEventArgs
che accompagna questo evento ha SelectedItem
proprietà e SelectedItemIndex
.
Quando la SelectionMode
proprietà è impostata su Single
, è possibile selezionare un singolo elemento in ListView . Quando si seleziona un elemento, la SelectedItem
proprietà verrà impostata sul valore dell'elemento selezionato. Quando questa proprietà viene modificata, viene generato l'evento ItemSelected
.
L'esempio seguente mostra un oggetto ListView in grado di rispondere alla selezione di un singolo elemento:
<ListView ItemsSource="{Binding Monkeys}"
ItemSelected="OnItemSelected">
...
</ListView>
In questo esempio il OnItemSelected
gestore eventi viene eseguito quando viene generato l'evento ItemSelected
, con il gestore eventi che recupera l'elemento selezionato:
void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
Monkey item = args.SelectedItem as Monkey;
}
Lo screenshot seguente mostra la selezione di un singolo elemento in un oggetto ListView:
Cancellare la selezione
La SelectedItem
proprietà può essere cancellata impostandola o l'oggetto a cui è associato, a null
.
Disabilita selezione
ListView la selezione è abilitata per impostazione predefinita. Tuttavia, può essere disabilitato impostando la SelectionMode
proprietà su None
:
<ListView ...
SelectionMode="None" />
Quando la SelectionMode
proprietà è impostata su None
, gli elementi in ListView non possono essere selezionati, la SelectedItem
proprietà rimarrà null
e l'evento ItemSelected
non verrà generato.
Dati cache
ListView è una visualizzazione potente per la visualizzazione dei dati, ma presenta alcune limitazioni. Le prestazioni di scorrimento possono risentire quando si usano celle personalizzate, soprattutto quando contengono gerarchie di visualizzazione annidate in profondità o si usano determinati layout che richiedono una misurazione complessa. Fortunatamente, esistono tecniche che è possibile usare per evitare prestazioni scarse.
Un ListView oggetto viene spesso usato per visualizzare molti più dati rispetto a quelli visualizzati sullo schermo. Ad esempio, un'app musicale potrebbe avere una libreria di canzoni con migliaia di voci. La creazione di un elemento per ogni voce potrebbe sprecare memoria preziosa e prestazioni scarse. La creazione e l'eliminazione costante di righe richiederebbero all'app di creare continuamente istanze e pulire gli oggetti, con prestazioni anche scarse.
Per risparmiare memoria, gli equivalenti nativi ListView per ogni piattaforma hanno funzionalità predefinite per il riutilizzo delle righe. Solo le celle visibili sullo schermo vengono caricate in memoria e il contenuto viene caricato nelle celle esistenti. Questo modello impedisce all'app di creare un'istanza di migliaia di oggetti, risparmiando tempo e memoria.
.NET MAUI consente il ListView riutilizzo delle celle tramite l'enumerazione ListViewCachingStrategy
, che definisce i membri seguenti:
RetainElement
, specifica che ListView genererà una cella per ogni elemento nell'elenco.RecycleElement
, specifica che ListView tenterà di ridurre al minimo il footprint di memoria e la velocità di esecuzione riciclando le celle dell'elenco.RecycleElementAndDataTemplate
, comeRecycleElement
anche per garantire che quando un utilizza un ListView DataTemplateSelectoroggetto , DataTemplate gli oggetti vengono memorizzati nella cache in base al tipo di elemento nell'elenco.
Mantieni elementi
La RetainElement
strategia di memorizzazione nella cache specifica che ListView genererà una cella per ogni elemento nell'elenco ed è il comportamento predefinito ListView . Deve essere usato nelle circostanze seguenti:
- Ogni cella ha un numero elevato di associazioni (20-30+).
- Il modello di cella cambia frequentemente.
- Il test rivela che la strategia di
RecycleElement
memorizzazione nella cache comporta una riduzione della velocità di esecuzione.
È importante riconoscere le conseguenze della strategia di RetainElement
memorizzazione nella cache quando si lavora con celle personalizzate. Qualsiasi codice di inizializzazione delle celle dovrà essere eseguito per ogni creazione di cella, che può essere più volte al secondo. In questa circostanza, le tecniche di layout che erano belle in una pagina, come l'uso di più oggetti annidati Grid , diventano colli di bottiglia delle prestazioni quando vengono configurati e distrutti in tempo reale mentre l'utente scorre.
Riciclare gli elementi
La RecycleElement
strategia di memorizzazione nella cache specifica che ListView tenterà di ridurre al minimo il footprint di memoria e la velocità di esecuzione riciclando le celle dell'elenco. Questa modalità non offre sempre un miglioramento delle prestazioni e i test devono essere eseguiti per determinare eventuali miglioramenti. Tuttavia, è la scelta preferita e deve essere usata nelle circostanze seguenti:
- Ogni cella ha un numero ridotto o moderato di associazioni.
- Ogni cella
BindingContext
definisce tutti i dati delle celle. - Ogni cella è in gran parte simile, con il modello di cella che non cambia.
Durante la virtualizzazione la cella avrà aggiornato il contesto di associazione e pertanto, se un'app usa questa modalità, deve assicurarsi che gli aggiornamenti del contesto di associazione vengano gestiti in modo appropriato. Tutti i dati relativi alla cella devono provenire dal contesto di associazione o possono verificarsi errori di coerenza. Questo problema può essere evitato usando il data binding per visualizzare i dati delle celle. In alternativa, i dati delle celle devono essere impostati nell'override OnBindingContextChanged
, anziché nel costruttore della cella personalizzata, come illustrato nell'esempio seguente:
public class CustomCell : ViewCell
{
Image image = null;
public CustomCell()
{
image = new Image();
View = image;
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var item = BindingContext as ImageItem;
if (item != null)
{
image.Source = item.ImageUrl;
}
}
}
Riciclare gli elementi con un oggetto DataTemplateSelector
Quando un ListView oggetto usa un DataTemplateSelector oggetto per selezionare un DataTemplateoggetto , la RecycleElement
strategia di memorizzazione nella cache non memorizza nella cache DataTemplate gli oggetti. Viene invece selezionato un oggetto DataTemplate per ogni elemento di dati nell'elenco.
Nota
La RecycleElement
strategia di memorizzazione nella cache richiede che quando viene richiesto a un oggetto DataTemplateSelector di selezionare un DataTemplate oggetto che deve DataTemplate restituire lo stesso ViewCell tipo. Ad esempio, dato un ListView oggetto con che DataTemplateSelector può restituire MyDataTemplateA
(dove MyDataTemplateA
restituisce un ViewCell di tipo MyViewCellA
) o MyDataTemplateB
(dove MyDataTemplateB
restituisce un ViewCell di tipo MyViewCellB
), quando MyDataTemplateA
viene restituito deve restituire MyViewCellA
o verrà generata un'eccezione.
Riciclare gli elementi con DataTemplate
La RecycleElementAndDataTemplate
strategia di memorizzazione nella cache si basa sulla RecycleElement
strategia di memorizzazione nella cache assicurando inoltre che quando un ListView oggetto usa per DataTemplateSelector selezionare un DataTemplateoggetto , DataTemplate gli oggetti vengono memorizzati nella cache in base al tipo di elemento nell'elenco. Pertanto, DataTemplate gli oggetti vengono selezionati una volta per ogni tipo di elemento, anziché una volta per ogni istanza dell'elemento.
Nota
La RecycleElementAndDataTemplate
strategia di memorizzazione nella cache richiede che DataTemplate gli oggetti restituiti da DataTemplateSelector devono usare il DataTemplate costruttore che accetta un oggetto Type
.
Impostare la strategia di memorizzazione nella cache
La strategia di ListView memorizzazione nella cache può essere definita da in XAML impostando l'attributo CachingStrategy
:
<ListView CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In C# la strategia di memorizzazione nella cache viene impostata tramite un overload del costruttore:
ListView listView = new ListView(ListViewCachingStrategy.RecycleElement);
Impostare la strategia di memorizzazione nella cache in un controllo ListView sottoclassato
L'impostazione dell'attributo CachingStrategy
da XAML in una sottoclassata ListView non produrrà il comportamento desiderato, perché non esiste alcuna CachingStrategy
proprietà in ListView. La soluzione a questo problema consiste nel specificare un costruttore nella sottoclassata ListView che accetta un ListViewCachingStrategy
parametro e lo passa alla classe base:
public class CustomListView : ListView
{
public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
{
}
...
}
È quindi possibile specificare il ListViewCachingStrategy
valore di enumerazione da XAML usando l'attributo x:Arguments
:
<local:CustomListView>
<x:Arguments>
<ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
</x:Arguments>
</local:CustomListView>
Intestazioni e piè di pagina
ListView può presentare un'intestazione e un piè di pagina che scorrono con gli elementi nell'elenco. L'intestazione e il piè di pagina possono essere stringhe, viste o DataTemplate oggetti.
ListView definisce le proprietà seguenti per specificare l'intestazione e il piè di pagina:
Header
, di tipoobject
, specifica la stringa, l'associazione o la vista che verrà visualizzata all'inizio dell'elenco.HeaderTemplate
, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggettoHeader
.Footer
, di tipoobject
, specifica la stringa, l'associazione o la vista che verrà visualizzata alla fine dell'elenco.FooterTemplate
, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggettoFooter
.
Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding.
Visualizzare stringhe nell'intestazione e nel piè di pagina
Le Header
proprietà e Footer
possono essere impostate su string
valori, come illustrato nell'esempio seguente:
<ListView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2022">
...
</ListView>
Lo screenshot seguente mostra l'intestazione risultante:
Visualizzare le visualizzazioni nell'intestazione e nel piè di pagina
Le Header
proprietà e Footer
possono essere impostate su una visualizzazione. Può trattarsi di una singola visualizzazione o di una visualizzazione che contiene più visualizzazioni figlio. Nell'esempio seguente vengono illustrate le Header
proprietà e Footer
ognuna di esse impostata su un Grid oggetto che contiene un Label oggetto :
<ListView ItemsSource="{Binding Monkeys}">
<ListView.Header>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</ListView.Header>
<ListView.Footer>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Monkey"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</ListView.Footer>
...
</ListView>
Lo screenshot seguente mostra l'intestazione risultante:
Visualizzare un'intestazione e un piè di pagina basato su modelli
Le HeaderTemplate
proprietà e FooterTemplate
possono essere impostate su DataTemplate oggetti utilizzati per formattare l'intestazione e il piè di pagina. In questo scenario, le Header
proprietà e Footer
devono essere associate all'origine corrente per applicare i modelli, come illustrato nell'esempio seguente:
<ListView ItemsSource="{Binding Monkeys}"
Header="{Binding .}"
Footer="{Binding .}">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Monkeys"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.FooterTemplate>
<DataTemplate>
<Grid BackgroundColor="LightGray">
<Label Margin="10,0,0,0"
Text="Friends of Monkey"
FontSize="12"
FontAttributes="Bold" />
</Grid>
</DataTemplate>
</ListView.FooterTemplate>
...
</ListView>
Separatori degli elementi di controllo
Per impostazione predefinita, i separatori vengono visualizzati tra ListView gli elementi in iOS e Android. Questo comportamento può essere modificato impostando la SeparatorVisibility
proprietà , di tipo SeparatorVisibility
, su None
:
<ListView ...
SeparatorVisibility="None" />
Inoltre, quando il separatore è abilitato, è possibile impostare il colore con la SeparatorColor
proprietà :
<ListView ...
SeparatorColor="Blue" />
Dimensioni elementi
Per impostazione predefinita, tutti gli elementi di un oggetto ListView hanno la stessa altezza, che deriva dal contenuto di DataTemplate che definisce l'aspetto di ogni elemento. Tuttavia, questo comportamento può essere modificato con le HasUnevenRows
proprietà e RowHeight
. Per impostazione predefinita, la HasUnevenRows
proprietà è false
.
La RowHeight
proprietà può essere impostata su un oggetto int
che rappresenta l'altezza di ogni elemento nell'oggetto ListView, a condizione che HasUnevenRows
sia false
. Quando HasUnevenRows
è impostato su true
, ogni elemento in ListView può avere un'altezza diversa. L'altezza di ogni elemento verrà derivata dal contenuto dell'elemento DataTemplatee quindi ogni elemento verrà ridimensionato in base al relativo contenuto.
I singoli ListView elementi possono essere ridimensionati a livello di codice in fase di esecuzione modificando le proprietà correlate al layout degli elementi all'interno di DataTemplate, purché la HasUnevenRows
proprietà sia true
. Nell'esempio seguente viene modificata l'altezza di un Image oggetto quando viene toccata:
void OnImageTapped(object sender, EventArgs args)
{
Image image = sender as Image;
ViewCell viewCell = image.Parent.Parent as ViewCell;
if (image.HeightRequest < 250)
{
image.HeightRequest = image.Height + 100;
viewCell.ForceUpdateSize();
}
}
In questo esempio, il OnImageTapped
gestore eventi viene eseguito in risposta a un Image oggetto che viene toccato. Il gestore eventi aggiorna l'altezza di Image e il Cell.ForceUpdateSize
metodo aggiorna le dimensioni della cella, anche quando non è attualmente visibile.
Avviso
L'uso eccessivo del dimensionamento di elementi dinamici può causare ListView un peggioramento delle prestazioni.
Layout da destra a sinistra
ListView può eseguire il layout del contenuto in una direzione del flusso da destra a sinistra impostandone la FlowDirection
proprietà su RightToLeft
. Tuttavia, la FlowDirection
proprietà deve essere impostata idealmente in un layout di pagina o radice, causando la risposta di tutti gli elementi all'interno della pagina o del layout radice alla direzione del flusso:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListViewDemos.RightToLeftListPage"
Title="Right to left list"
FlowDirection="RightToLeft">
<Grid Margin="20">
<ListView ItemsSource="{Binding Monkeys}">
...
</ListView>
</Grid>
</ContentPage>
Il valore predefinito FlowDirection
per un elemento con un elemento padre è MatchParent
. Pertanto, ListView eredita il valore della FlowDirection
proprietà da Grid, che a sua volta eredita il valore della FlowDirection
ContentPageproprietà da .
Visualizzare i dati raggruppati
I set di dati di grandi dimensioni possono spesso diventare difficili quando vengono presentati in un elenco a scorrimento continuo. In questo scenario, l'organizzazione dei dati in gruppi può migliorare l'esperienza utente semplificando l'esplorazione dei dati.
I dati devono essere raggruppati prima di poter essere visualizzati. A tale scopo, è possibile creare un elenco di gruppi, in cui ogni gruppo è un elenco di elementi. L'elenco dei gruppi deve essere una IEnumerable<T>
raccolta, in cui T
definisce due parti di dati:
- Nome del gruppo.
- Raccolta
IEnumerable
che definisce gli elementi appartenenti al gruppo.
Il processo di raggruppamento dei dati è quindi:
- Creare un tipo che modella un singolo elemento.
- Creare un tipo che modella un singolo gruppo di elementi.
- Creare una
IEnumerable<T>
raccolta, doveT
è il tipo che modella un singolo gruppo di elementi. Questa raccolta è una raccolta di gruppi che archivia i dati raggruppati. - Aggiungere dati alla
IEnumerable<T>
raccolta.
Esempio
Quando si raggruppano i dati, il primo passaggio consiste nel creare un tipo che modella un singolo elemento. L'esempio seguente illustra la Animal
classe :
public class Animal
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
La Animal
classe modella un singolo elemento. È quindi possibile creare un tipo che modella un gruppo di elementi. L'esempio seguente illustra la AnimalGroup
classe :
public class AnimalGroup : List<Animal>
{
public string Name { get; private set; }
public AnimalGroup(string name, List<Animal> animals) : base(animals)
{
Name = name;
}
}
La AnimalGroup
classe eredita dalla List<T>
classe e aggiunge una Name
proprietà che rappresenta il nome del gruppo.
È quindi possibile creare una IEnumerable<T>
raccolta di gruppi:
public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();
Questo codice definisce una raccolta denominata Animals
, in cui ogni elemento dell'insieme è un AnimalGroup
oggetto . Ogni AnimalGroup
oggetto comprende un nome e una List<Animal>
raccolta che definisce gli Animal
oggetti nel gruppo.
I dati raggruppati possono quindi essere aggiunti alla Animals
raccolta:
Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
new Animal
{
Name = "American Black Bear",
Location = "North America",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
},
new Animal
{
Name = "Asian Black Bear",
Location = "Asia",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
},
// ...
}));
Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
new Animal
{
Name = "Baboon",
Location = "Africa & Asia",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
},
new Animal
{
Name = "Capuchin Monkey",
Location = "Central & South America",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
},
new Animal
{
Name = "Blue Monkey",
Location = "Central and East Africa",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
},
// ...
}));
Questo codice crea due gruppi nella Animals
raccolta. Il primo AnimalGroup
è denominato Bears
e contiene una List<Animal>
raccolta di dettagli dell'orso. Il secondo AnimalGroup
è denominato Monkeys
e contiene una List<Animal>
raccolta di dettagli della scimmia.
ListView visualizzerà i dati raggruppati, purché i dati siano stati raggruppati correttamente, impostando la IsGroupingEnabled
proprietà su true
:
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Il codice C# equivalente è il seguente:
ListView listView = new ListView
{
IsGroupingEnabled = true
};
listView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...
L'aspetto di ogni elemento in ListView è definito impostando la relativa ItemTemplate
proprietà su un oggetto DataTemplate. Per altre informazioni, vedere Definire l'aspetto dell'elemento.
Lo screenshot seguente mostra i ListView dati raggruppati visualizzati:
Nota
Per impostazione predefinita, ListView visualizzerà il nome del gruppo nell'intestazione del gruppo. Questo comportamento può essere modificato personalizzando l'intestazione del gruppo.
Personalizzare l'intestazione del gruppo
L'aspetto di ogni intestazione di gruppo può essere personalizzato impostando la ListView.GroupHeaderTemplate
proprietà su :DataTemplate
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Name}"
BackgroundColor="LightGray"
FontSize="18"
FontAttributes="Bold" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
...
</ListView>
In questo esempio, ogni intestazione di gruppo è impostata su un Label oggetto che visualizza il nome del gruppo e con altre proprietà di aspetto impostate. Lo screenshot seguente mostra l'intestazione del gruppo personalizzata:
Importante
La GroupHeaderTemplate
proprietà si escludono a vicenda con la GroupDisplayBinding
proprietà . Pertanto, entrambe le proprietà non devono essere impostate.
Raggruppare senza modelli
ListViewpuò visualizzare correttamente i dati raggruppati senza impostare la ItemTemplate
proprietà su :DataTemplate
<ListView ItemsSource="{Binding Animals}"
IsGroupingEnabled="true" />
In questo scenario è possibile visualizzare dati significativi eseguendo l'override del ToString
metodo nel tipo che modella un singolo elemento e il tipo che modella un singolo gruppo di elementi.
Scorrimento dei controlli
ListView definisce due ScrollTo
metodi, che scorrono gli elementi nella visualizzazione. Uno degli overload scorre l'elemento specificato nella visualizzazione, mentre l'altro scorre l'elemento specificato nel gruppo specificato nella visualizzazione. Entrambi gli overload hanno argomenti aggiuntivi che consentono di specificare la posizione esatta dell'elemento dopo il completamento dello scorrimento e se animare lo scorrimento.
ListView definisce un ScrollToRequested
evento generato quando viene richiamato uno dei ScrollTo
metodi. L'oggetto ScrollToRequestedEventArgs
che accompagna l'evento ScrollToRequested
ha molte proprietà, tra cui ShouldAnimate
, Mode
Element, e Position
. Alcune di queste proprietà vengono impostate dagli argomenti specificati nelle chiamate al ScrollTo
metodo.
Definisce inoltre ListView un Scrolled
evento generato per indicare che si è verificato lo scorrimento. L'oggetto ScrolledEventArgs
che accompagna l'evento Scrolled
ha ScrollX
proprietà e ScrollY
.
Rilevare lo scorrimento
ListView definisce un Scrolled
evento generato per indicare che si è verificato lo scorrimento. La ItemsViewScrolledEventArgs
classe , che rappresenta l'oggetto che accompagna l'evento Scrolled
, definisce le proprietà seguenti:
ScrollX
, di tipodouble
, rappresenta la posizione X dello scorrimentoScrollY
, di tipodouble
, rappresenta la posizione Y dello scorrimento.
L'esempio XAML seguente mostra un ListView oggetto che imposta un gestore eventi per l'evento Scrolled
:
<ListView Scrolled="OnListViewScrolled">
...
</ListView>
Il codice C# equivalente è il seguente:
ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;
In questo esempio di codice, il OnListViewScrolled
gestore eventi viene eseguito quando viene generato l'evento Scrolled
:
void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
// Custom logic
}
Importante
L'evento Scrolled
viene generato per gli scorrimenti avviati dall'utente e per gli scorrimenti a livello di codice.
Scorrere un elemento nella visualizzazione
Il ScrollTo
metodo scorre l'elemento specificato nella visualizzazione. Dato un ListView oggetto denominato listView
, l'esempio seguente mostra come scorrere l'elemento Proboscis Monkey nella visualizzazione:
MonkeysViewModel viewModel = BindingContext as MonkeysViewModel;
Monkey monkey = viewModel.Monkeys.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, ScrollToPosition.MakeVisible, true);
In alternativa, è possibile scorrere un elemento in dati raggruppati nella visualizzazione specificando l'elemento e il gruppo. L'esempio seguente mostra come scorrere l'elemento Scimmia Proboscis nel gruppo Monkeys in visualizzazione:
GroupedAnimalsViewModel viewModel = BindingContext as GroupedAnimalsViewModel;
AnimalGroup group = viewModel.Animals.FirstOrDefault(a => a.Name == "Monkeys");
Animal monkey = group.FirstOrDefault(m => m.Name == "Proboscis Monkey");
listView.ScrollTo(monkey, group, ScrollToPosition.MakeVisible, true);
Nota
L'evento ScrollToRequested
viene generato quando viene richiamato il ScrollTo
metodo .
Disabilitare l'animazione di scorrimento
Quando si scorre un elemento nella visualizzazione, viene visualizzata un'animazione di scorrimento. Tuttavia, questa animazione può essere disabilitata impostando l'argomento animated
del ScrollTo
metodo su false
:
listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: false);
Posizione di scorrimento del controllo
Quando si scorre un elemento nella visualizzazione, è possibile specificare la posizione esatta dell'elemento dopo il completamento dello scorrimento con l'argomento position
dei ScrollTo
metodi . Questo argomento accetta un ScrollToPosition
membro di enumerazione.
MakeVisible
Il ScrollToPosition.MakeVisible
membro indica che l'elemento deve essere scorrevole fino a quando non è visibile nella visualizzazione:
listView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible, animate: true);
Inizio
Il ScrollToPosition.Start
membro indica che l'elemento deve essere scorrevole fino all'inizio della visualizzazione:
listView.ScrollTo(monkey, position: ScrollToPosition.Start, animate: true);
Centro
Il ScrollToPosition.Center
membro indica che l'elemento deve essere scorrevole fino al centro della visualizzazione:
listView.ScrollTo(monkey, position: ScrollToPosition.Center, animate: true);
Fine
Il ScrollToPosition.End
membro indica che l'elemento deve essere scorrevole fino alla fine della visualizzazione:
listView.ScrollTo(monkey, position: ScrollToPosition.End, animate: true);
Visibilità barra di scorrimento
ListView definisce HorizontalScrollBarVisibility
le proprietà e VerticalScrollBarVisibility
supportate dalle proprietà associabili. Queste proprietà ottengono o impostano un ScrollBarVisibility
valore di enumerazione che rappresenta quando la barra di scorrimento orizzontale o verticale è visibile. L'enumerazione ScrollBarVisibility
definisce i membri seguenti:
Default
indica il comportamento predefinito della barra di scorrimento per la piattaforma ed è il valore predefinito per leHorizontalScrollBarVisibility
proprietà eVerticalScrollBarVisibility
.Always
indica che le barre di scorrimento saranno visibili, anche quando il contenuto rientra nella visualizzazione.Never
indica che le barre di scorrimento non saranno visibili, anche se il contenuto non rientra nella visualizzazione.
Aggiungere menu di scelta rapida
ListView supporta gli elementi dei menu di scelta rapida, definiti come MenuItem oggetti aggiunti all'insieme ViewCell.ContextActions
in DataTemplate per ogni elemento:
<ListView x:Name="listView"
ItemsSource="{Binding Monkeys}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Favorite"
Command="{Binding Source={x:Reference listView}, Path=BindingContext.FavoriteCommand}"
CommandParameter="{Binding}" />
<MenuItem Text="Delete"
Command="{Binding Source={x:Reference listView}, Path=BindingContext.DeleteCommand}"
CommandParameter="{Binding}" />
</ViewCell.ContextActions>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Gli MenuItem oggetti vengono visualizzati quando si fa clic con il pulsante destro del ListView mouse su un elemento in :
Per altre informazioni sulle voci di menu, vedere Visualizzare le voci di menu.
Funzionalità Trascina verso il basso
ListView supporta la funzionalità pull per l'aggiornamento, che consente di aggiornare i dati visualizzati trascinando verso il basso nell'elenco di elementi.
Per abilitare l'aggiornamento tramite pull, impostare la IsPullToRefreshEnabled
proprietà su true
. Quando viene attivato un aggiornamento, ListView genera l'evento Refreshing
e la IsRefreshing
proprietà verrà impostata su true
. Il codice necessario per aggiornare il contenuto di ListView deve quindi essere eseguito dal gestore per l'evento Refreshing
o dall'implementazione eseguita dall'oggetto ICommand RefreshCommand
. Dopo l'aggiornamento ListView di , la IsRefreshing
proprietà deve essere impostata su false
o il EndRefresh
metodo deve essere chiamato in ListViewper indicare che l'aggiornamento è stato completato.
Nell'esempio seguente viene illustrato un ListView oggetto che usa il pull per l'aggiornamento:
<ListView ItemsSource="{Binding Animals}"
IsPullToRefreshEnabled="true"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In questo esempio, quando l'utente avvia un aggiornamento, viene eseguito l'oggetto ICommand definito dalla RefreshCommand
proprietà , che deve aggiornare gli elementi visualizzati. Viene visualizzata una visualizzazione di aggiornamento mentre si verifica l'aggiornamento, costituito da un cerchio di stato animato. Il valore della IsRefreshing
proprietà indica lo stato corrente dell'operazione di aggiornamento. Quando viene attivato un aggiornamento, questa proprietà passerà automaticamente a true
. Al termine dell'aggiornamento, è necessario reimpostare la proprietà su false
.