Creazione di un'interfaccia utente interattiva

Completato

Tech logo.

Nelle lezioni precedenti è stata creata l'interfaccia utente di un modulo semplice, che chiede all'utente di immettere un nome e di visualizzare un messaggio di saluto con un pulsante. In questa lezione si rende il modulo più semplice da usare, disabilitando o nascondendo il pulsante Submit finché non vengono immessi almeno tre caratteri.

Prima di tutto si esaminerà quando esattamente viene impostato il valore MainPageLogic.UserName tramite il binding.

1. Posizionare un punto di interruzione

Aprire il file MainPageLogic.cs e individuare la riga che contiene la proprietà UserName.

public string UserName { get; set; }

Impostare un punto di interruzione nel setter spostando il cursore all'interno del testo set e premendo F9. È possibile eseguire questa operazione anche facendo clic con il pulsante destro del mouse su set e scegliendo Punto di interruzione/Inserisci punto di interruzione.

2. Eseguire l'app in modalità di debug

Eseguire quindi l'app in modalità di debug (F5 o Debug/Avvia debug). Digitare qualcosa in TextBox e notare che il punto di interruzione non viene raggiunto. Se si preme il tasto TAB, lo stato attivo per l'input passerà al controllo successivo, in questo caso, il pulsante. La perdita dello stato attivo in TextBox aggiorna il binding e quindi il punto di interruzione viene raggiunto.

3. Modificare l'associazione in modo che venga aggiornata in ogni sequenza di tasti

Arrestare il debug premendo MAIUSC + F5 o selezionando Debug/Arresta debug.

Per fornire un feedback preciso sul momento in cui abilitare il pulsante Submit, non è possibile aspettare che venga perso lo stato attivo in TextBox. Per fortuna, è possibile cambiare il comportamento del binding. È possibile forzarlo ad aggiornare la proprietà UserName (ovvero l'origine, dato che si tratta di un binding TwoWay) ogni volta che la proprietà Text cambia. È necessario cambiare UpdateSourceTrigger del binding, che per impostazione predefinita è impostato su LostFocus. UpdateSourceTrigger definisce la circostanza che attiva l'aggiornamento dell'origine.

Aprire MainPage.xaml e individuare il tag TextBox. Cambiare quindi il binding aggiungendo UpdateSourceTrigger=PropertyChanged. L'intero tag TextBox ha ora l'aspetto seguente:

<TextBox Name="tbUserName" 
         Margin="10" 
         Width="150" 
         VerticalAlignment="Center" 
         Text="{x:Bind Logic.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Se si esegue il debug dell'app a questo punto, è possibile vedere che il punto di interruzione viene raggiunto ogni volta che si preme un tasto e che il testo cambia. Ottimo.

Come forse si ricorderà, quando è stato usato il binding da interfaccia utente a interfaccia utente per visualizzare il messaggio di saluto, tale binding veniva attivato a ogni pressione di tasto. In tal caso, il binding era definito in TextBlock e quindi l'origine era la proprietà TextBox.Text, che cambia a ogni pressione di tasto. UpdateSourceTrigger influisce sul flusso di dati nella direzione opposta. Il flusso è dall'origine di associazione al controllo su cui è definito il binding (destinazione del binding).

5. Aggiungere la IsSubmitAllowed proprietà

Aggiungere quindi una proprietà booleana che indica se l'invio del modulo è consentito. Aprire MainPageLogic.cs e aggiungere una nuova proprietà alla classe MainPageLogic.

public bool IsSubmitAllowed => UserName?.Trim().Length > 2;

Si tratta di una convalida molto semplice: se il testo immesso, dopo che sono stati eliminati gli spazi iniziali e finali, contiene più di due caratteri, viene accettato come nome utente.

6. Valutare di nuovo IsSubmitAllowed dopo ogni modifica a UserName

È necessario indicare al framework interfaccia utente quando valutare di nuovo questa proprietà e rifletterla nell'interfaccia utente. Il modo migliore per attivare questa rivalutazione è chiamare RaisePropertyChanged nel setter della proprietà UserName. Per poter aggiungere codice al setter, è necessario convertirlo in una proprietà completa. Sostituire la proprietà UserName con il codice seguente:

private string _userName;
public string UserName
{
    get { return _userName; }
    set
    {
        _userName = value;
        RaisePropertyChanged(nameof(IsSubmitAllowed));
    }
}

Per questa proprietà non si usa INotifyPropertyChanged, perché non esiste ancora uno scenario in cui la proprietà UserName viene modificata dal codice. Tuttavia, ogni volta che in TextBox il testo cambia, è necessario indicare all'interfaccia utente che la proprietà IsSubmitAllowed potrebbe essere cambiata e deve essere valutata di nuovo.

7. Associare la IsSubmitAllowed proprietà alla proprietà del IsEnabled pulsante

Il lavoro con il codice è terminato. Tornare a MainPage.xaml e individuare il pulsante Submit. Aggiungere l'attributo IsEnabled in modo che il codice XAML del pulsante sia simile al seguente:

<Button Margin="10" 
        VerticalAlignment="Center" 
        Click="{x:Bind Logic.Submit}" 
        IsEnabled="{x:Bind Logic.IsSubmitAllowed, Mode=OneWay}">Submit</Button>

8. Eseguire l'app

Se ora si esegue l'app, si dovrebbe notare che il pulsante Submit è disabilitato per impostazione predefinita. Il pulsante rimane disabilitato se si digitano alcuni spazi e viene abilitato solo quando vengono immessi almeno tre caratteri diversi dallo spazio.

Anche se questo esempio esegue alcune operazioni di convalida, la piattaforma UWP offre un set avanzato di funzionalità di convalida che saranno illustrate in un modulo successivo.

Screenshot of app, with Submit button disabled.

9. Nascondere il pulsante Invia

Lo sviluppatore o il progettista potrebbe decidere di compiere un ulteriore passo avanti e di tenere nascosto il pulsante Submit finché non sia possibile premerlo. Questa è una modifica semplice da apportare, quindi procediamo. È sufficiente modificare il codice XAML, sostituendo IsEnabled con Visibility.

Screenshot of app, with Submit button hidden.

Se tuttavia si digitano alcuni caratteri, si vede che l'intera interfaccia utente si sposta. L'oggetto StackPanel circostante, infatti, è centrato orizzontalmente (HorizontalAlignment="Center") e la larghezza di StackPanel è minore quando Button è compresso. Per risolvere questo problema, è possibile inserire Button in un oggetto Border con larghezza pari a 100, come questo.

<Border Width="100">
    <Button Margin="10" 
            VerticalAlignment="Center" 
            Click="{x:Bind Logic.Submit}" 
            Visibility="{x:Bind Logic.IsSubmitAllowed, Mode=OneWay}">Submit</Button>
</Border>

Con questa modifica la larghezza di StackPanel non cambia quando l'oggetto Button all'interno di Border viene visualizzato di nuovo.

Riepilogo

In questa lezione si è visto come eseguire il debug del binding. È stata illustrata l'opzione di binding UpdateSourceTrigger e sono stati esaminati altri esempi di data binding. Si è anche visto un esempio di come sia possibile modificare l'aspetto e il comportamento dell'interfaccia utente senza modificare il codice C#, se si usa il data binding nel modo appropriato.

Nella lezione successiva si esaminerà come usare il data binding per visualizzare più elementi in un elenco.

Tech logo.

Nelle lezioni precedenti è stata creata l'interfaccia utente di un modulo semplice, che chiede all'utente di immettere un nome e di visualizzare un messaggio di saluto con un pulsante. In questa lezione si rende il modulo più semplice da usare, disabilitando o nascondendo il pulsante Submit finché non vengono immessi almeno tre caratteri.

Prima di tutto si esaminerà quando esattamente viene impostato il valore MainWindowDataContext.UserName tramite il binding.

1. Posizionare un punto di interruzione

Aprire il file MainWindowDataContext.cs e individuare la riga che contiene la proprietà UserName.

public string UserName { get; set; }

Impostare un punto di interruzione nel setter spostando il cursore all'interno del testo set e premendo F9. È anche possibile eseguire questa operazione facendo clic con il pulsante destro del mouse su set e scegliendo Punto di interruzione/Inserisci punto di interruzione.

2. Eseguire l'app in modalità di debug

Eseguire quindi l'app in modalità di debug (F5 o Debug/Avvia debug). Digitare qualcosa in TextBox. Notare che il punto di interruzione non viene raggiunto. Se si preme il tasto TAB, lo stato attivo per l'input passerà al controllo successivo, in questo caso, il pulsante. La perdita dello stato attivo in TextBox aggiorna il binding e quindi il punto di interruzione viene raggiunto.

3. Modificare l'associazione in modo che venga aggiornata in ogni sequenza di tasti

Arrestare il debug premendo MAIUSC + F5 o selezionando Debug/Arresta debug.

Per fornire un feedback preciso sul momento in cui abilitare il pulsante Submit, non è possibile aspettare che venga perso lo stato attivo in TextBox. Per fortuna, è possibile cambiare il comportamento del binding. È possibile forzarlo ad aggiornare la proprietà UserName (ovvero l'origine, dato che si tratta di un binding TwoWay) ogni volta che la proprietà Text cambia. È necessario cambiare UpdateSourceTrigger del binding, che per impostazione predefinita è impostato su LostFocus. UpdateSourceTrigger definisce la circostanza che attiva l'aggiornamento dell'origine.

Aprire MainWindow.xaml e trovare l'elemento TextBox. Cambiare quindi il binding aggiungendo UpdateSourceTrigger=PropertyChanged. L'intero tag TextBox ha ora l'aspetto seguente:

<TextBox Name="tbName" 
         Margin="10" 
         Width="150" 
         VerticalAlignment="Center" 
         Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Se si esegue il debug dell'app a questo punto, è possibile vedere che il punto di interruzione viene raggiunto ogni volta che si preme un tasto e che il testo cambia. Ottimo.

Come forse si ricorderà, quando è stato usato il binding da interfaccia utente a interfaccia utente per visualizzare il messaggio di saluto, il binding veniva attivato a ogni pressione di tasto. In tal caso, il binding era definito in TextBlock e quindi l'origine era la proprietà TextBox.Text, che cambia a ogni pressione di tasto. UpdateSourceTrigger influisce sul flusso di dati nella direzione opposta. Il flusso è dall'origine di associazione al controllo su cui è definito il binding (destinazione del binding).

5. Aggiungere la IsSubmitAllowed proprietà

Aggiungere quindi una proprietà booleana che indica se l'invio del modulo è consentito. AprireMainWindowDataContext.cs e aggiungere una nuova proprietà alla classe MainWindowDataContext.

public bool IsSubmitAllowed => !string.IsNullOrWhiteSpace(UserName);

Questa proprietà esegue una semplice convalida. Se il testo immesso non è null, vuoto o composto solo da spazi vuoti, viene accettato come nome utente.

6. Valutare di nuovo IsSubmitAllowed dopo ogni modifica a UserName

È necessario indicare al framework interfaccia utente quando ripetere la valutazione di questa proprietà e rifletterla nell'interfaccia utente. Il modo migliore per attivare questa rivalutazione è chiamare RaisePropertyChanged nel setter della proprietà UserName. Per poter aggiungere codice al setter, è necessario convertirlo in una proprietà completa. Sostituire la proprietà UserName con il codice seguente:

private string? _userName;
public string? UserName
{
    get { return _userName; }
    set
    {
        _userName = value;
        RaisePropertyChanged(nameof(IsSubmitAllowed));
    }
}

Per questa proprietà non si usa INotifyPropertyChanged, perché non esiste uno scenario in cui la proprietà UserName viene modificata dal codice. Tuttavia, ogni volta che in TextBox il testo cambia, è necessario indicare all'interfaccia utente che la proprietà IsSubmitAllowed potrebbe essere cambiata e deve essere valutata di nuovo.

7. Associare la IsSubmitAllowed proprietà alla proprietà del IsEnabled pulsante

Il lavoro con il codice è terminato. Tornare a MainWindow.xaml e individuare il pulsante Submit. Aggiungere l'attributo IsEnabled in modo che il codice XAML del pulsante sia simile al seguente:

<Button Margin="10" 
        VerticalAlignment="Center" 
        Click="OnSubmitClicked"
        IsEnabled="{Binding IsSubmitAllowed}">Submit</Button>

8. Eseguire l'app

Se ora si esegue l'app, si dovrebbe notare che il pulsante Submit è disabilitato per impostazione predefinita. Verrà abilitato non appena si inizia a digitare.

Anche se questo esempio esegue alcune operazioni di convalida di base, WPF offre un set avanzato di funzionalità di convalida che saranno illustrate in un modulo successivo.

Screenshot of app, with Submit button disabled.

Riepilogo

In questa lezione si è visto come eseguire il debug del binding. È stata illustrata l'opzione di binding UpdateSourceTrigger e sono stati esaminati altri esempi di data binding. Si è anche visto un esempio di come, se si usa il data binding nel modo appropriato, sia possibile modificare l'aspetto e il comportamento dell'interfaccia utente senza modificare il codice C#.

Nella lezione successiva si esaminerà come usare il data binding per visualizzare più elementi in un elenco.