Aggiornamento dell'interfaccia utente quando cambiano le raccolte

Completato

In questa lezione l'utente selezionerà i colori preferiti. I colori disponibili sono visualizzati in un elenco a discesa (un controllo ComboBox). L'utente seleziona un colore e lo aggiunge ai preferiti premendo un pulsante. I colori preferiti sono visualizzati di seguito. Quando si seleziona un colore preferito, viene anche visualizzato un pulsante che consente all'utente di rimuovere il colore selezionato dai preferiti.

Screenshot of sample databinding app running and displaying favorite colors.

Aggiungere prima di tutto la possibilità di selezionare un colore nella raccolta LotsOfColors e aggiungerlo all'elenco dei colori preferiti.

1. Creare la SelectedColor proprietà

Si inizierà con il codice, per poi passare all'interfaccia utente.

È necessario un modo per determinare quale elemento (ovvero istanza della classe ColorDescriptor) l'utente seleziona nell'elenco a discesa. Il controllo ComboBox ha una proprietà SelectedItem che ottiene e imposta l'elemento attualmente selezionato. È quindi possibile associare questa proprietà a una proprietà di tipo ColorDescriptor nel codice.

Aprire ColorListLogic.cs e aggiungere il codice seguente:

private ColorDescriptor _selectedColor;

public ColorDescriptor SelectedColor
{
    get => _selectedColor;
    set => Set(ref _selectedColor, value);
}

Il modello a questo punto dovrebbe risultare familiare. Si tratta di una proprietà standard, decorata con il meccanismo INotifyPropertyChanged, con il supporto della classe di base ObservableObject.

2. Creare l'elenco FavoriteColors

L'elenco FavoriteColors archivia i colori che l'utente ha scelto come preferiti. Si tratta di una proprietà semplice.

public List<ColorDescriptor> FavoriteColors { get; } = 
    new List<ColorDescriptor>();

3. Aggiungere il colore selezionato ai preferiti

L'aggiunta del colore selezionato ai preferiti avviene nel metodo AddSelectedColorToFavorites.

public void AddSelectedColorToFavorites()
{
    FavoriteColors.Add(SelectedColor);
}

Il presupposto è che quando questo metodo viene chiamato, in SelectedColor viene inserito il colore che deve essere aggiunto all'elenco dei preferiti.

Per il momento, il lavoro con il codice è terminato. Si passerà quindi a XAML.

4. Modificare l'oggetto ListBox in un ComboBox

Poiché si vuole che l'elenco completo dei colori venga visualizzato in un elenco a discesa (ovvero un controllo ComboBox), è necessario modificare il codice XAML. Fortunatamente, sia ListBox che ComboBox sono discendenti del controllo ItemsControl e funzionano in modo simile, nonostante le differenze nell'aspetto e nel comportamento. È sufficiente sostituire ListBox con ComboBox nel file ColorList.xaml. A tale scopo, è possibile usare il comando Modifica>Trova e sostituisci>Sostituzione veloce (CTRL+H).

Screenshot of Visual Studio showing the Quick Replace command.

Se ora si esegue rapidamente l'app, è possibile notare che ListBox è stato sostituito con un oggetto ComboBox, ma i colori vengono comunque visualizzati usando lo stesso modello.

Screenshot of favorite colors app showing the color selection combo box.

5. Estrarre il modello in una risorsa

Per quanto riguarda il modello, sarà necessario riutilizzarlo più avanti per l'elenco dei colori preferiti. È consigliabile archiviare il modello in un'unica posizione, in modo che il codice XAML risulti più leggibile. E, cosa ancora più importante, ciò garantisce che le modifiche apportate al modello vengano applicate a tutte le istanze. Estrarre il modello in una risorsa.

Qualsiasi oggetto FrameworkElement può avere un elenco di risorse. È stato scelto di rendere il modello globale per questa pagina: aggiungere quindi un tag <Page.Reources> sopra l'elemento <Grid>. Quindi, spostare l'intero tag <DataTemplate> e il relativo contenuto al suo interno.

<Page.Resources>
    <DataTemplate x:DataType="local:ColorDescriptor">
        <StackPanel Orientation="Horizontal">
            <Rectangle Width="30" 
                       Height="30">
                <Rectangle.Fill>
                    <SolidColorBrush Color="{x:Bind Color}"/>
                </Rectangle.Fill>
            </Rectangle>
            <TextBlock Text="{x:Bind Name}" 
                       Margin="20, 10, 0, 10"/>
        </StackPanel>
    </DataTemplate>
</Page.Resources>

Visual Studio avvisa l'utente che gli oggetti inclusi nel tag <Page.Resources> (che è un IDictionary) devono avere un attributo Key. Aggiungerlo quindi a <DataTemplate>.

<DataTemplate x:Key="ColorTemplate" 
              x:DataType="local:ColorDescriptor">

Questa chiave consente di fare riferimento al modello da un'altra posizione della pagina, ad esempio ComboBox.ItemTemplate, che ha perso il relativo contenuto. Per fare in modo che ComboBox usi la risorsa ColorDescriptor, è possibile rimuovere il tag <ComboBox.ItemTemplate> e usarlo come attributo all'interno del tag <ComboBox>. L'intero tag <ComboBox> avrà un aspetto simile al seguente:

<ComboBox ItemsSource="{x:Bind Logic.LotsOfColors}" 
          Margin="20" 
          Width="200"
          HorizontalAlignment="Left" 
          VerticalAlignment="Top"
          ItemTemplate="{StaticResource ColorTemplate}"/>

È possibile eseguire di nuovo l'app per verificare il funzionamento del modello di elemento.

6. Compilare il resto dell'interfaccia utente

L'interfaccia utente è semplice. Tutti i controlli, ovvero l'elenco a discesa, il pulsante Add to Favorites, l'elenco dei preferiti (con il testo di intestazione) e il pulsante Remove from Favorites, si trovano in un singolo oggetto StackPanel verticale. Sostituire l'intero contenuto dell'elemento <Grid> con quanto segue:

<StackPanel>
    <ComboBox ItemsSource="{x:Bind Logic.LotsOfColors}" 
              Margin="20, 20, 20, 0" 
              Width="200"
              HorizontalAlignment="Left" 
              VerticalAlignment="Top"
              ItemTemplate="{StaticResource ColorTemplate}"
              SelectedItem="{x:Bind Logic.SelectedColor, Mode=TwoWay}" 
              />

    <Button Margin="20" 
            Click="{x:Bind Logic.AddSelectedColorToFavorites}">Add to Favorites</Button>
    <TextBlock FontSize="25" 
               Margin="20, 20, 20, 0">Favorite colors</TextBlock>

    <ListBox ItemsSource="{x:Bind Logic.FavoriteColors}"
             ItemTemplate="{StaticResource ColorTemplate}"
             Margin="20, 20, 20, 0"/>

    <Button Margin="20">Remove from Favorites</Button>
</StackPanel>

È presente un binding TwoWay tra l'elemento attualmente selezionato in ComboBox e la proprietà SelectedColor della classe ColorListLogic.

7. Eseguire l'app

Eseguire ora l'app, selezionare un colore in ComboBox e fare clic sul pulsante Add to Favorites. Non accade nulla. Aggiungendo un punto di interruzione alla fine del metodo AddSelectedColorToFavorites nella classe ColorListLogic si noterà che il codice funziona. Il colore selezionato viene aggiunto all'elenco FavoriteColors.

L'interfaccia utente non riflette le modifiche in List<ColorDescriptor> perché deve ricevere una notifica quando la raccolta cambia. Per gli elenchi, tale risultato viene ottenuto attraverso l'interfaccia System.Collections.Specialized.INotifyCollectionChanged. Fortunatamente, non è necessario implementare questo aspetto. La classe System.Collections.ObjectModel.ObservableCollection<T> offre già tutto il necessario.

Per far funzionare l'app, è sufficiente usare la classe ObservableCollection<T> invece della classe List<T> per la proprietà FavoriteColors.

public ObservableCollection<ColorDescriptor> FavoriteColors { get; } = 
    new ObservableCollection<ColorDescriptor>();

Se si esegue l'app a questo punto, quando si selezionano i colori nell'elenco a discesa e si fa clic sul pulsante Add to Favorites, viene implementato il comportamento corretto. I colori preferiti selezionati vengono aggiunti a ListBox. Fantastico!

Screenshot of sample app showing favorite colors added to list.

8. Evitare di aggiungere elementi vuoti

Quando si avvia l'app, non c'è alcun colore selezionato nell'elenco a discesa. Se si seleziona Add to Favorites a questo punto, all'elenco vengono aggiunti valori null. Si tratta di un bug, pertanto è necessario correggerlo.

Sarebbe possibile aggiungere un controllo dei valori null al metodo AddSelectedColorToFavorites, ma ciò non impedirebbe la visualizzazione del pulsante Add to Favorites quando non è funzionale. È preferibile invece fare in modo che vi sia sempre un elemento selezionato nell'elenco a discesa. Poiché la proprietà SelectedItem dell'elenco a discesa è associata tramite binding bidirezionale alla proprietà SelectedColor nel codice, è sufficiente eseguirne l'inizializzazione con un valore valido all'avvio. Aggiungere la riga seguente alla fine del costruttore ColorListLogic:

SelectedColor = LotsOfColors[0];

In questo modo è possibile garantire che il primo elemento dell'elenco LotsOfColors venga selezionato all'avvio dell'app. L'utente non sarà in grado di aggiungere un oggetto null alla raccolta FavoriteColors.

9. Rimuovere i colori preferiti

Il passaggio successivo consiste nell'aggiungere la possibilità di rimuovere i colori preferiti da ListBox. Ciò avviene quando l'utente seleziona un elemento in ListBox e quindi fa clic sul pulsante Remove from Favorites.

Analogamente al funzionamento di ComboBox, è possibile tenere traccia dell'elemento selezionato dall'utente in ListBox tramite la proprietà SelectedItem. È possibile eseguire il binding a una proprietà nel codice. Aggiungere la proprietà alla classe ColorListLogic.

private ColorDescriptor _selectedFavoriteColor;

public ColorDescriptor SelectedFavoriteColor
{
    get => _selectedFavoriteColor;
    set
    {
        Set(ref _selectedFavoriteColor, value);
        RaisePropertyChanged(nameof(IsRemoveFavoriteColorButtonVisible));
    }
}

public bool IsRemoveFavoriteColorButtonVisible => SelectedFavoriteColor != null;

Il codice precedente include anche una proprietà booleana per controllare se il pulsante per rimuovere gli elementi dall'elenco dei preferiti deve essere visibile. In seguito a qualsiasi modifica a SelectedFavoriteColor, l'interfaccia utente esegue una query su questa proprietà e si comporta di conseguenza.

Per eseguire effettivamente la rimozione del colore dall'elenco dei preferiti, è necessario scrivere un altro metodo.

public void RemoveFavoriteColor()
{
    FavoriteColors.Remove(SelectedFavoriteColor);
}

Per collegare il pulsante nel codice XAML, aprire ColorList.xaml e modificare il codice XAML del pulsante Remove from Favorites. Apportare le modifiche necessarie per includere il binding di Visibility, oltre che il binding di Click.

<Button Margin="20" 
        Visibility="{x:Bind Logic.IsRemoveFavoriteColorButtonVisible, Mode=OneWay}"
        Click="{x:Bind Logic.RemoveFavoriteColor}">Remove from Favorites</Button>

A questo punto non resta che eseguire il binding di SelectedItem di ListBox alla proprietà Logic.SelectedFavoriteColor. Aggiungere l'attributo SelectedItem a ListBox nel codice XAML.

<ListBox SelectedItem="{x:Bind Logic.SelectedFavoriteColor, Mode=TwoWay}"... >

Eseguire ora l'app e verificare che sia possibile aggiungere colori all'elenco dei colori preferiti, oltre che rimuoverli. Si noti che il pulsante Remove from Favorites viene visualizzato e nascosto in base al fatto che sia selezionato o meno un colore preferito che può essere rimosso.

Riepilogo

In questa lezione è stato illustrato come acquisire e impostare l'elemento selezionato in un controllo ComboBox o ListBox, eseguendo il binding delle relative proprietà SelectedItem a una proprietà C#. Si è visto anche come l'uso di ObservableCollection nel codice comporti l'aggiornamento automatico, nell'interfaccia utente, dei contenuti dei controlli che visualizzano più elementi.

In questa lezione l'utente selezionerà i colori preferiti. I colori disponibili sono visualizzati in un elenco a discesa (un controllo ComboBox). L'utente seleziona un colore e lo aggiunge ai preferiti premendo un pulsante. I colori preferiti sono visualizzati sotto l'elenco completo. Quando si seleziona un colore preferito, viene anche visualizzato un pulsante che consente all'utente di rimuovere il colore selezionato dai preferiti.

Screenshot of sample app showing selected favorite color with remove button available.

Aggiungere prima di tutto la possibilità di selezionare un colore nella raccolta LotsOfColors e aggiungerlo all'elenco dei colori preferiti.

1. Creare la SelectedColor proprietà

Si inizierà con il codice, per poi passare alle modifiche dell’interfaccia utente.

È necessario un modo per determinare quale elemento (ovvero istanza della classe ColorDescriptor) l'utente seleziona nell'elenco a discesa. Il controllo ComboBox ha una proprietà SelectedItem che ottiene e imposta l'elemento attualmente selezionato. È quindi possibile associare questa proprietà a una proprietà di tipo ColorDescriptor nel codice.

Aprire ColorListDataContext.cs e aggiungere il codice seguente:

private ColorDescriptor? _selectedColor;

public ColorDescriptor? SelectedColor
{
    get => _selectedColor;
    set => Set(ref _selectedColor, value);
}

Il modello a questo punto dovrebbe risultare familiare. Si tratta di una proprietà standard, utilizzata con il meccanismo INotifyPropertyChanged, con il supporto della classe di base ObservableObject.

2. Creare l'elenco FavoriteColors

L'elenco FavoriteColors archivia i colori che l'utente ha scelto come preferiti. Si tratta di una proprietà semplice.

public List<ColorDescriptor> FavoriteColors { get; } = 
    new List<ColorDescriptor>();

3. Aggiungere il colore selezionato ai preferiti

L'aggiunta del colore selezionato ai preferiti avviene nel metodo AddSelectedColorToFavorites. Per precauzione, verificare se la SelectedColor proprietà è null. In caso affermativo, restituire dal metodo. In caso contrario, aggiungere il colore selezionato all'elenco FavoriteColors.

public void AddSelectedColorToFavorites()
{
    if (SelectedColor == null) return;
    FavoriteColors.Add(SelectedColor);
}

Quando questo metodo viene richiamato, SelectedColor deve essere riempito con il colore aggiunto all'elenco preferiti, ma è consigliabile non fare ipotesi.

Per il momento, il lavoro con il codice è terminato. Si passerà quindi a XAML.

4. Modificare l'oggetto ListBox in un ComboBox

Poiché si vuole che l'elenco completo dei colori venga visualizzato in un elenco a discesa (ovvero un controllo ComboBox), è necessario modificare il codice XAML. Fortunatamente, sia ListBox che ComboBox sono discendenti del controllo ItemsControl e funzionano in modo simile, nonostante le numerose differenze nell'aspetto e nel comportamento. È sufficiente sostituire ListBox con ComboBox nel file ColorList.xaml. A tale scopo, è possibile usare il comando Modifica>Trova e sostituisci>Sostituzione veloce (CTRL+H).

Repeat screenshot of Visual Studio showing Quick Replace command.

Se ora si esegue rapidamente l'app, è possibile notare che ListBox è stato sostituito con un oggetto ComboBox, ma i colori vengono comunque visualizzati usando lo stesso modello.

Screenshot of sample app showing color list in a ComboBox.

5. Estrarre il modello in una risorsa

Per quanto riguarda il modello, sarà necessario riutilizzarlo più avanti per l'elenco dei colori preferiti. È consigliabile archiviare il modello in un'unica posizione, in modo che il codice XAML risulti più leggibile. E, cosa ancora più importante, ciò garantisce che le modifiche apportate al modello vengano applicate a tutte le istanze. Estrarre il modello in una risorsa.

Qualsiasi oggetto FrameworkElement può avere un elenco di risorse. È stato scelto di rendere il modello globale per l'intero oggetto Window: aggiungere quindi un tag <Window.Reources> sopra l'elemento <Grid>. Quindi, spostare l'intero tag <DataTemplate> e il relativo contenuto al suo interno.

<Window.Resources>
    <DataTemplate x:Key="ColorTemplate">
        <StackPanel Orientation="Horizontal">
            <Rectangle Width="80" 
                       Height="20">
                <Rectangle.Fill>
                    <SolidColorBrush Color="{Binding Color}"/>
                </Rectangle.Fill>
            </Rectangle>
            <TextBlock Text="{Binding Name}" 
                       Margin="20, 10, 0, 10"/>
        </StackPanel>
    </DataTemplate>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>

<Window.Resources> è un dizionario, quindi ogni voce deve avere anche una chiave. È stato aggiunto all'oggetto <DataTemplate>.

<DataTemplate x:Key="ColorTemplate">

Questa chiave consente di fare riferimento al modello da un'altra posizione all'interno di Window, ad esempio ComboBox.ItemTemplate, che ha perso il relativo contenuto. Per fare in modo che ComboBox usi la risorsa ColorDescriptor, è possibile rimuovere il tag <ComboBox.ItemTemplate> e usarlo come attributo all'interno del tag <ComboBox>. L'intero tag <ComboBox> avrà un aspetto simile al seguente:

<ComboBox ItemsSource="{x:Bind Logic.LotsOfColors}" 
          Margin="20" 
          Width="200"
          HorizontalAlignment="Left" 
          VerticalAlignment="Top"
          ItemTemplate="{StaticResource ColorTemplate}"/>

È possibile eseguire di nuovo l'app per verificare il funzionamento del modello di elemento.

6. Compilare il resto dell'interfaccia utente

L'interfaccia utente è semplice. Tutti i controlli, ovvero l'elenco a discesa, il pulsante Add to Favorites, l'elenco dei preferiti (con il testo di intestazione) e il pulsante Remove from Favorites, sono annidati in un singolo oggetto StackPanel verticale. Sostituire l'intero elemento <Grid> con quanto segue:

<StackPanel>
    <ComboBox ItemsSource="{Binding LotsOfColors}" 
              Margin="20, 20, 20, 0" 
              Width="200"
              HorizontalAlignment="Left" 
              VerticalAlignment="Top"
              ItemTemplate="{StaticResource ColorTemplate}"
              SelectedItem="{Binding SelectedColor, Mode=TwoWay}" />

    <Button 
        Margin="20" 
        HorizontalAlignment="Left">Add to Favorites</Button>

    <TextBlock
            FontSize="25" 
            Margin="20, 20, 20, 0">Favorite colors</TextBlock>

    <ListBox ItemsSource="{Binding FavoriteColors}"
             ItemTemplate="{StaticResource ColorTemplate}"
             Margin="20, 20, 20, 0"
             HorizontalAlignment="Left"/>

    <Button Margin="20" 
            HorizontalAlignment="Left">Remove from Favorites</Button>

</StackPanel>

È presente un binding TwoWay tra l'elemento attualmente selezionato in ComboBox e la proprietà SelectedColor della classe ColorListDataContext.

7. Creare il gestore Click per il Add to Favorites pulsante

È già stata implementata la logica per l'aggiunta del colore selezionato all'elenco FavoriteColors nel metodo AddSelectedColorToFavorites. Tuttavia, è necessario richiamare questo metodo quando l'utente fa clic sul pulsante.

Fare doppio clic sul pulsante Add to Favorites nella finestra di progettazione grafica in Visual Studio. Vengono creati un metodo Button_Click nel code-behind e un riferimento a esso nell'evento Click in XAML:

<Button ... Click="Button_Click">Add to Favorites</Button>

Rinominare il metodo Button_Click in AddToFavorites_Click sia nel code-behind che in XAML. A tale scopo, è possibile eseguire l'operazione di ridenominazione nel codice e quindi, usando l'icona a forma di cacciavite, selezionare "Rinomina Button_Click in AddToFavorites_Click". In questo modo verrà modificato anche il nome del metodo nel file XAML.

Screenshot of Visual Studio quick action option to rename button click method..

Aggiungere una proprietà pratica all'inizio della classe ColorList per semplificare l'accesso a ColorListDataContext:

private ColorListDataContext DC => (ColorListDataContext)DataContext;

Quindi, nel metodo AddToFavorites_Click richiamare la logica scritta in precedenza dalla classe ColorListDataContext:

private void AddToFavorites_Click(object sender, RoutedEventArgs e)
{
    DC.AddSelectedColorToFavorites();
}

8. Eseguire l'app

Eseguire ora l'app, selezionare un colore in ComboBox e fare clic sul pulsante Add to Favorites. Non accade nulla. Aggiungendo un punto di interruzione alla fine del metodo AddSelectedColorToFavorites nella classe ColorListDataContext si noterà che il codice funziona. Il colore selezionato viene aggiunto all'elenco FavoriteColors.

L'interfaccia utente non riflette le modifiche in List<ColorDescriptor> perché deve ricevere una notifica quando la raccolta cambia. Per gli elenchi, tale risultato viene ottenuto attraverso l'interfaccia System.Collections.Specialized.INotifyCollectionChanged. Fortunatamente, non è necessario implementare questo aspetto. La classe System.Collections.ObjectModel.ObservableCollection<T> offre già tutto il necessario.

Per far funzionare l'app, è sufficiente usare la classe ObservableCollection<T> invece della classe List<T> per la proprietà FavoriteColors.

public ObservableCollection<ColorDescriptor> FavoriteColors { get; } = 
    new ObservableCollection<ColorDescriptor>();

Se si esegue l'app a questo punto, quando si selezionano i colori nell'elenco a discesa e si fa clic sul pulsante Add to Favorites, viene implementato il comportamento corretto. I colori preferiti selezionati vengono aggiunti a ListBox. Fantastico!

Screenshot of sample app showing selected color added to favorites.

9. Evitare di aggiungere elementi vuoti

Quando si avvia l'app, non c'è alcun colore selezionato nell'elenco a discesa. Attualmente è disponibile un null controllo nel AddSelectedColorToFavorites metodo per impedire l'aggiunta di elementi "Null" all'elenco quando si seleziona il pulsante Aggiungi a Preferiti. Modificare questa opzione per assicurarsi che sia sempre selezionato un colore nell'elenco a discesa.

Il controllo null non impedirebbe la visualizzazione del pulsante Aggiungi a Preferiti quando non è funzionale. Quindi, è sufficiente assicurarsi che sia sempre presente un elemento selezionato. Poiché la proprietà SelectedItem dell'elenco a discesa è associata tramite binding bidirezionale alla proprietà SelectedColor nel codice, è sufficiente eseguirne l'inizializzazione con un valore valido all'avvio. Aggiungere la riga seguente alla fine del costruttore ColorListDataContext:

SelectedColor = LotsOfColors[0];

In questo modo è possibile garantire che il primo elemento dell'elenco LotsOfColors venga selezionato all'avvio dell'app. L'utente non sarà in grado di aggiungere un oggetto null alla raccolta FavoriteColors.

10. Rimuovere i colori preferiti

Il passaggio successivo consiste nell'aggiungere la possibilità di rimuovere i colori preferiti da ListBox. Ciò avviene quando l'utente seleziona un elemento in ListBox e quindi fa clic sul pulsante Remove from Favorites.

Analogamente al funzionamento di ComboBox, è possibile tenere traccia dell'elemento selezionato dall'utente in ListBox tramite la proprietà SelectedItem. È possibile eseguire il binding a una proprietà nel codice. Aggiungere una nuova proprietà alla classe ColorListDataContext, come segue:

private ColorDescriptor? _selectedFavoriteColor;

public ColorDescriptor? SelectedFavoriteColor
{
    get => _selectedFavoriteColor;
    set
    {
        Set(ref _selectedFavoriteColor, value);
        RaisePropertyChanged(nameof(IsRemoveFavoriteEnabled));
    }
}

public bool IsRemoveFavoriteEnabled => SelectedFavoriteColor != null;

Il codice precedente include anche una proprietà booleana per controllare se il pulsante per rimuovere gli elementi dall'elenco dei preferiti deve essere visibile. In seguito a qualsiasi modifica a SelectedFavoriteColor, l'interfaccia utente esegue una query su questa proprietà e si comporta di conseguenza.

Per eseguire effettivamente la rimozione del colore dall'elenco dei preferiti, è necessario scrivere un altro metodo.

public void RemoveFavoriteColor()
{
    if (SelectedFavoriteColor == null) return;
    FavoriteColors.Remove(SelectedFavoriteColor);
}

A questo punto, eseguire il binding di SelectedItem di ListBox alla proprietà SelectedFavoriteColor. Aggiungere l'attributo SelectedItem alla ListBox in CodeList.xaml.

<ListBox SelectedItem="{Binding SelectedFavoriteColor, Mode=TwoWay}"... >

Per collegare il pulsante Rimuovi dai preferiti, modificare il codice XAML del pulsante Rimuovi dai preferiti in modo da includere il binding di IsEnabled, oltre al gestore dell'evento Click.

<Button Margin="20" 
        HorizontalAlignment="Left"
        Click="RemoveFromFavorites_Click"
        IsEnabled="{Binding IsRemoveFavoriteEnabled}">Remove from Favorites</Button>

Occorre anche aggiungere il metodo RemoveFromFavorites_Click a ColorList.xaml.cs per chiamare RemoveFromFavoriteColor nella logica.

private void RemoveFromFavorites_Click(object sender, RoutedEventArgs e)
{
    DC.RemoveFavoriteColor();
}

Eseguire ora l'app e verificare che sia possibile aggiungere colori all'elenco dei colori preferiti, oltre che rimuoverli. Si noti che il pulsante Remove from Favorites viene abilitato e disabilitato in base al fatto che sia selezionato o meno un colore preferito che può essere rimosso.

Come esercizio, provare a nascondere l'intera sezione Favorite Colors dell'interfaccia utente quando la raccolta FavoriteColors è vuota. Suggerimento: usare un elemento StackPanel per raggruppare i controlli interessati ed eseguire il binding di Visibility di StackPanel a una proprietà della classe ColorListDataContext. Ogni volta che un colore preferito viene aggiunto o rimosso, indicare all'interfaccia utente le modifiche apportate a questa proprietà.

Riepilogo

In questa lezione è stato illustrato come acquisire e impostare l'elemento selezionato in un controllo ComboBox o ListBox eseguendo il binding delle relative proprietà SelectedItem a una proprietà C#. Si è visto anche come l'uso di ObservableCollection nel codice comporti l'aggiornamento automatico, nell'interfaccia utente, dei contenuti dei controlli che visualizzano più elementi.